@semics-tech/emdash-esign-pro 1.0.0-rc.10 → 1.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +1 -1
- package/dist/manifest.json +1 -1
- package/dist/plugin.mjs +2 -2
- package/package.json +1 -1
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.12",
|
|
11
11
|
"format": "standard",
|
|
12
12
|
"entrypoint": "@semics-tech/emdash-esign-pro/sandbox",
|
|
13
13
|
"capabilities": [
|
package/dist/manifest.json
CHANGED
package/dist/plugin.mjs
CHANGED
|
@@ -6,7 +6,7 @@ function e(e,t,n,r=``){let i={...e};for(let[e,a]of Object.entries(t??{})){if(Obj
|
|
|
6
6
|
`))}function vn(e){let t=[],n=(e,n)=>{typeof n==`string`&&n!==``&&t.push(`/${e} ${Zt(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=Qt(e.creationDate);n&&t.push(`/CreationDate (${n})`)}return`<< ${t.join(` `)} >>`}function yn(e){let t=hn(e.page),n=_n(t,e.blocks,e.footer),r=[`<< /Type /Catalog /Pages 2 0 R >>`,``,vn(e.info)],i=Rt.map(e=>(r.push(`<< /Type /Font /Subtype /Type1 /BaseFont /${e.baseFont} /Encoding /WinAnsiEncoding >>`),`/${e.resource} ${r.length} 0 R`)).join(` `),a=`[0 0 ${N(t.width)} ${N(t.height)}]`,o=[];for(let e of n){r.push($t(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} >>`,en(r,1,3)}async function bn(e,t){let n=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(`${t}:${e}`));return E(new Uint8Array(n).slice(0,16))}async function xn(e,t,n,r){let i=Math.floor(n/(r.windowSeconds*1e3)),a=`rl:${r.scope}:${await bn(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?O(`RATE_LIMITED`):(await e.set(a,`${s+1}:${(i+1)*r.windowSeconds}`,{ttlSeconds:r.windowSeconds*2}),D({remaining:r.limit-s-1}))}async function Sn(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 Cn=`cron:scheduled:v11`,wn=`ensure-schedules`;async function Tn(e,t){try{if(await e.kv.get(Cn))return;await e.cron?.schedule(wn,{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 Dn(e,t,n){await En(e,t)&&await e.kv.set(Cn,{at:new Date(n).toISOString()})}async function On(e,t,n,r){return e.name===wn?(await Dn(t,n,r),!0):!1}function kn(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 Tn(i,n()),r(e,i));return{...e,handler:i}}var jn=class extends Error{code=`TEMPLATE_MISSING_FIELD`;constructor(e){super(`Template field "${e}" has no value`),this.field=e,this.name=`TemplateError`}};const Mn=/\{\{\s*([A-Za-z_][A-Za-z0-9_.]*)\s*\}\}/g,Nn={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};function Pn(e){return e.replace(/\s*[\r\n]+\s*/g,` `).replace(/[\\&<>"'#[\]()*_`~|{}+!-]/g,e=>Nn[e]??`\\${e}`)}function Fn(e){return[...new Set([...e.matchAll(Mn)].map(e=>e[1]))]}function In(e,t){return e.replace(Mn,(e,n)=>{let r=Object.hasOwn(t,n)?t[n]:void 0;if(r===void 0)throw new jn(n);return Pn(String(r))})}function Ln(e){return`${e.replace(/^/,``).replace(/\r\n?/g,`
|
|
7
7
|
`).normalize(`NFC`).split(`
|
|
8
8
|
`).map(e=>e.replace(/[ \t]+$/,``)).join(`
|
|
9
|
-
`).replace(/\n+$/,``)}\n`}async function P(e){let t=typeof e==`string`?new TextEncoder().encode(e):new Uint8Array(e);return E(await crypto.subtle.digest(`SHA-256`,t))}async function Rn(e,t){if(!t.token)return O(`TURNSTILE_FAILED`);let n=new URLSearchParams({secret:t.secret,response:t.token});t.remoteIp&&n.set(`remoteip`,t.remoteIp);try{let t=await e(`https://challenges.cloudflare.com/turnstile/v0/siteverify`,{method:`POST`,body:n});return t.ok&&(await t.json()).success===!0?D(!0):O(`TURNSTILE_FAILED`)}catch{return O(`TURNSTILE_FAILED`)}}function zn(e){try{return e?new URL(e).host:``}catch{return``}}function Bn(e){if(!e.ok)return e.error===`LICENCE_EXPIRED`?{status:`expired`,code:`LICENCE_EXPIRED`}:{status:`invalid`,code:`LICENCE_INVALID`};let t=e.value;if(t.kind===`exempt`)return{status:`exempt`,hostname:t.hostname};let{customer:n,sites:r,updatesUntil:i}=t.licence;return{status:`licensed`,hostname:t.hostname,customer:n,sites:r,updatesUntil:i}}function Vn(e){return e===`new`||e===`in-flight`?e:ce[e]}function Hn(e,t={}){let n=Dt(e),r=async e=>n({key:await e.settings.get(`licenceKey`),hostname:zn(e.site?.url)});return{build:e,check:r,gate(e,t){let n=Vn(e);if(n===`in-flight`)return t;let i=typeof t==`function`?t:t.handler,a=async(e,t)=>{let a=le(await r(t),n);return a.ok?i(e,t):se(a.error).body};return typeof t==`function`?a:{...t,handler:a}},statusRoute(){return{handler:async(n,i)=>({ok:!0,edition:`pro`,product:e.product,buildDate:e.buildDate,devKey:t.devKey??!1,licence:Bn(await r(i))})}}}}const Un={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},Wn=e=>e.replace(/[&<>"']/g,e=>Un[e]),Gn=e=>e.replace(/\s*[\r\n]+\s*/g,` `),Kn=/\{\{(\w+)\}\}/g;function qn(e,t,n){return e.replace(Kn,(e,r)=>n(t[r]??``))}const Jn=`January February March April May June July August September October November December`.split(` `);function Yn(e){let t=new Date(e);return`${t.getUTCDate()} ${Jn[t.getUTCMonth()]} ${t.getUTCFullYear()}`}function Xn(e,t,n){let r=Object.fromEntries(Object.entries(n).map(([e,t])=>[e,Gn(t)]));return{to:e,subject:qn(t.subject,r,e=>e),text:qn(t.text,r,e=>e),html:qn(t.html,r,Wn)}}function Zn(e){let t=e.expiresAt?`This request expires on ${Yn(e.expiresAt)}.`:``;return Xn(e.to,{subject:`{{sender}} asks you to sign: {{title}}`,text:`Hello {{name}},
|
|
9
|
+
`).replace(/\n+$/,``)}\n`}async function P(e){let t=typeof e==`string`?new TextEncoder().encode(e):new Uint8Array(e);return E(await crypto.subtle.digest(`SHA-256`,t))}async function Rn(e,t){if(!t.token)return O(`TURNSTILE_FAILED`);let n=new URLSearchParams({secret:t.secret,response:t.token});t.remoteIp&&n.set(`remoteip`,t.remoteIp);try{let t=await e(`https://challenges.cloudflare.com/turnstile/v0/siteverify`,{method:`POST`,body:n});return t.ok&&(await t.json()).success===!0?D(!0):O(`TURNSTILE_FAILED`)}catch{return O(`TURNSTILE_FAILED`)}}function zn(e){try{return e?new URL(e).host:``}catch{return``}}function Bn(e){if(!e.ok)return e.error===`LICENCE_EXPIRED`?{status:`expired`,code:`LICENCE_EXPIRED`}:{status:`invalid`,code:`LICENCE_INVALID`};let t=e.value;if(t.kind===`exempt`)return{status:`exempt`,hostname:t.hostname};let{customer:n,sites:r,updatesUntil:i}=t.licence;return{status:`licensed`,hostname:t.hostname,customer:n,sites:r,updatesUntil:i}}function Vn(e){return e===`new`||e===`in-flight`?e:ce[e]}function Hn(e,t={}){let n=Dt(e),r=async e=>n({key:await e.settings.get(`licenceKey`),hostname:zn(e.site?.url)});return{build:e,check:r,gate(e,t){let n=Vn(e);if(n===`in-flight`)return t;let i=typeof t==`function`?t:t.handler,a=async(e,t)=>{let a=le(await r(t),n);return a.ok?i(e,t):se(a.error).body};return typeof t==`function`?a:{...t,handler:a}},statusRoute(){return{handler:async(n,i)=>({ok:!0,edition:`pro`,product:e.product,buildDate:e.buildDate,devKey:t.devKey??!1,licence:Bn(await r(i))})}}}}new TextEncoder;const Un={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},Wn=e=>e.replace(/[&<>"']/g,e=>Un[e]),Gn=e=>e.replace(/\s*[\r\n]+\s*/g,` `),Kn=/\{\{(\w+)\}\}/g;function qn(e,t,n){return e.replace(Kn,(e,r)=>n(t[r]??``))}const Jn=`January February March April May June July August September October November December`.split(` `);function Yn(e){let t=new Date(e);return`${t.getUTCDate()} ${Jn[t.getUTCMonth()]} ${t.getUTCFullYear()}`}function Xn(e,t,n){let r=Object.fromEntries(Object.entries(n).map(([e,t])=>[e,Gn(t)]));return{to:e,subject:qn(t.subject,r,e=>e),text:qn(t.text,r,e=>e),html:qn(t.html,r,Wn)}}function Zn(e){let t=e.expiresAt?`This request expires on ${Yn(e.expiresAt)}.`:``;return Xn(e.to,{subject:`{{sender}} asks you to sign: {{title}}`,text:`Hello {{name}},
|
|
10
10
|
|
|
11
11
|
{{sender}} has asked you to review and sign "{{title}}" electronically.{{expiry}}
|
|
12
12
|
|
|
@@ -50,7 +50,7 @@ Grace Hopper <grace@example.com>`,...typeof o.signers==`string`?{initialValue:o.
|
|
|
50
50
|
`);function Jc(e){return e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,n,r]=e.split(`|`).map(e=>e.trim());return{key:t,label:n??``,...r?.toLowerCase()===`required`?{required:!0}:{}}})}async function Yc(e,t,n=[]){let r=await ps(e.ctx).pdf_templates.get(t);if(!r||r.status!==`active`)return W([i(`PDF templates`),...h([K(`error`,`Template not found`)]),g([Uc()])]);let o=r.pdf.pages.map((e,t)=>`page ${t+1}: ${e.w} x ${e.h}`).join(`, `);return W([i(`PDF template: ${r.name}`),...n,a(`${r.pdf.filename}, ${Wc(r.pdf.bytes)}, SHA-256 ${r.pdf.sha256}. Page sizes in points: ${o}.`),w({fields:[y(`name`,`Name`,{initialValue:r.name}),y(`signerFields`,`Signer fields: key | label | required (one per line)`,{initialValue:qc(r.signerFields),multiline:!0}),y(`fields`,`Fields: kind page x y width height [key] [signer=n] (kinds: signature, name, date, text)`,{initialValue:us(r.fields),multiline:!0,placeholder:`signature 1 72 650 200 50
|
|
51
51
|
name 1 72 710 200 18
|
|
52
52
|
date 1 320 710 120 18`})],submit:{label:`Save`,actionId:`pdft.save`},blockId:`pdft:${t}`}),w({fields:[y(`signerName`,`Signer's name`),y(`signerEmail`,`Signer's email`),y(`title`,`Title (optional)`)],submit:{label:`Send for signature`,actionId:`pdft.send`},blockId:`pdft-send:${t}`}),g([_(`pdft.archive`,`Archive`,{value:t,style:`danger`}),Uc()])])}const Xc=(e,t)=>e?.startsWith(t)?e.slice(t.length):``,Zc=(e,t,n)=>e.pdfTemplates(t,n);async function Qc(e,t){let n=typeof t==`string`?t.trim():G(t?.id);if(!n)return Kc(e,h([K(`error`,`Choose a PDF first`)]));let r=await Zc(e,`upload`,{mediaId:n});if(r.ok!==!0)return Kc(e,h([K(`error`,`Not uploaded`,Gc(r))]));let i=r.template;return Yc(e,i.id,h([K(`info`,`Uploaded`,`Now set the fields to stamp, then send it.`)]))}async function $c(e,t){if(t.type===`page_load`)return Kc(e);if(t.type===`block_action`){if(t.action_id===`pdft.upload`)return Qc(e,t.value);let n=G(t.value);if(t.action_id===`pdft.open`&&n)return Yc(e,n);if(t.action_id===`pdft.archive`&&n){let t=await Zc(e,`update`,{id:n,archived:!0});return Kc(e,h([t.ok?K(`info`,`Template archived`):K(`error`,`Not archived`,Gc(t))]))}return Kc(e)}let n=t.values;if(t.action_id===`pdft.save`){let r=Xc(t.block_id,`pdft:`),i=ls(typeof n.fields==`string`?n.fields:``);if(!i.ok)return Yc(e,r,h([K(`error`,`Not saved`,`Check field line ${i.error.join(`, `)}.`)]));let a=await Zc(e,`update`,{id:r,name:G(n.name),fields:i.value,signerFields:Jc(typeof n.signerFields==`string`?n.signerFields:``)});return Yc(e,r,h([a.ok?K(`info`,`Saved`):K(`error`,`Not saved`,Gc(a))]))}if(t.action_id===`pdft.send`){let r=Xc(t.block_id,`pdft-send:`),i=await Zc(e,`send`,{templateId:r,signer:{name:G(n.signerName),email:G(n.signerEmail,254)},...G(n.title)?{title:G(n.title)}:{}});return i.ok===!0?Yc(e,r,h([i.invitation===`SITE_URL_MISSING`?K(`warning`,`Sent, but no email`,`Set the site URL so invitations can link to the signing page.`):K(`info`,`Sent for signature`)])):Yc(e,r,h([K(`error`,`Not sent`,Gc(i))]))}return Kc(e)}const el=e=>e.type===`page_load`?e.page===`/pdf-templates`:e.action_id.startsWith(`pdft.`),tl=()=>pc(`selfserve.back`,`Back to self-serve forms`);async function nl(e,t=[]){let[n,r,o]=await Promise.all([mc(e.ctx),e.ctx.settings.get(`turnstileSiteKey`),e.ctx.settings.get(`turnstileSecretKey`)]),s=typeof r==`string`&&r!==``&&typeof o==`string`&&o!==``;return W([i(`Self-serve forms`),...h([!s&&K(`warning`,`Turnstile is not set up`,`A public form needs both Cloudflare Turnstile keys in Settings. Until then the form on your page says it is unavailable.`)]),...t,a(`Mark a template here, then add the Self-serve request block to a page and pick the template. A visitor types their name, email address and the template's fields; the signing link goes only to that address. The cap is how many visitors can start in a day (UTC).`),l({columns:[c(`name`,`Template`),c(`state`,`Self-serve`,`badge`),c(`cap`,`Per day`),c(`edit`,``,`element`)],rows:n.map(({id:e,data:t})=>({name:t.name,state:Ys(t)?`On`:`Off`,cap:Ys(t)?String(Xs(t)):``,edit:_(`selfserve.open`,`Edit`,{value:e})})),pageActionId:`selfserve.page`,emptyText:`No active templates. Create one on the Templates page.`})])}async function rl(e,t,n=[]){let r=await z(e.ctx).templates.get(t);return!r||r.status!==`active`?W([i(`Self-serve forms`),...h([K(`error`,`Template not found`)]),g([tl()])]):W([i(`Self-serve: ${r.name}`),...n,w({fields:[S(`enabled`,`Offer this template to visitors`,{initialValue:Ys(r)}),b(`dailyCap`,`Visitors per day`,{initialValue:r.selfServeDailyCap??50,min:1,max:Js})],submit:{label:`Save`,actionId:`selfserve.save`},blockId:`selfserve:${t}`}),g([tl()])])}async function il(e,t,n){let r=t?.startsWith(`selfserve:`)?t.slice(10):``;if(!r)return nl(e,h([K(`error`,`Choose a template first`)]));let i=n.enabled===!0,a=n.dailyCap,o=typeof a==`number`?a:typeof a==`string`&&a.trim()!==``?Number(a):void 0,s=await e.markSelfServe({id:r,enabled:i,...o===void 0?{}:{dailyCap:o}});if(s.ok!==!0)return rl(e,r,h([K(`error`,`Not saved`,s.error?.code===`BAD_REQUEST`?`The daily cap must be a whole number from 1 to ${Js}.`:s.error?.message??`The change was refused.`)]));let c=s.template;return nl(e,h([K(`info`,c.public?`Self-serve is on`:`Self-serve is off`,c.public?`Up to ${c.selfServeDailyCap} visitors a day can start from this template.`:`Visitors can no longer start from this template.`)]))}const al=e=>e.type===`page_load`?e.page===`/self-serve`:e.action_id.startsWith(`selfserve.`);async function ol(e,t){return t.type===`page_load`?nl(e):t.type===`form_submit`?il(e,t.block_id,t.values):t.action_id===`selfserve.open`?rl(e,G(t.value,200)):nl(e)}const sl=e=>typeof e==`function`?e:e.handler;function cl(e){try{return new URL(e.request?.url??``).origin}catch{return`http://localhost`}}function ll(e){let t=(t,n)=>sl(e.gate(t,{handler:n})),n=t(`esign/envelope-send`,qs),r=t(`esign/envelope-send`,ko),i=t(`new`,fc),a={upload:t(`new`,Es),update:t(`new`,Ds),send:t(`esign/envelope-send`,Os)};return e=>{let t=sl(e),o=async(e,o)=>{let s=e.input,c=e.user??null,l=e=>t=>e({input:t,user:c},o),u={ctx:o,origin:cl(e),now:Date.now(),user:c,sendSeveral:l(n),startBulk:l(r),markSelfServe:l(i),pdfTemplates:(e,t)=>l(a[e])(t)};if(wc(s))return Tc(u,s);if(al(s))return ol(u,s);if(el(s))return $c(u,s);if(s.type!==`page_load`&&Vc(s.action_id))return Hc(u,s);let d=s.type===`page_load`&&s.page===`/envelopes`||s.type===`block_action`&&s.action_id===`envelopes.back`?()=>Fc(u):s.type===`block_action`&&s.action_id===`envelope.open`?()=>zc(u,String(s.value??``).trim().slice(0,200)):null;if(!d)return t(e,o);let[f,p]=await Promise.all([t(e,o),d()]),m=f?.blocks;return Array.isArray(m)&&p.length>0?{...f,blocks:[...m,...p]}:f};return typeof e==`function`?o:{...e,handler:o}}}async function ul(e,t,n,r){let i=Eo(e),a=await i.getMany([t,so(t),oo(t,n),co(t)]),o=a.get(t),s=a.get(oo(t,n));if(!o||o.kind!==`job`||!s)return`skipped`;let c=M(r),l=n+1>=o.pages,u=async()=>{await e.cron?.schedule(uo(t,n+1),{schedule:c})},d=F(e);if(o.status===`cancelled`||a.has(co(t))||!d)return await i.deleteMany([oo(t,n),...l?[so(t),co(t)]:[]]),(o.status!==`cancelled`||!l)&&await i.putMany([{id:t,data:{...o,status:`cancelled`,updatedAt:c}}]),l||await u(),`cancelled`;let f=a.get(so(t))?.template,p=s.rows.filter(e=>e.status===`pending`),m=new Map,h=[],g={chunks:[],signers:[],envelopes:[],audit:[],mail:[]},_=tr(e,o.senderName);await Promise.all(p.map(async e=>{let n=t=>{m.set(e.seq,{seq:e.seq,status:`failed`,code:t}),h.push({seq:e.seq,code:t})};if(!f||!e.name||!e.email)return n(`TEMPLATE_NOT_FOUND`);let i=lo(t,e.seq),a=cr(),s=Zr({templateId:o.templateId,templateVersion:o.templateVersion,title:o.title,signer:{name:e.name,email:e.email,as:`self`},fieldValues:e.fields??{}},f,{now:c,piiSalt:a});if(!s.ok)return n(s.error[0]?.code??`BAD_REQUEST`);let l=k(),u=await oi(i,s.value,f,{now:c,tokenHash:await A(l),expiryDays:o.expiryDays});if(!u.ok)return n(Array.isArray(u.error)?u.error[0]?.code??`BAD_REQUEST`:`ENVELOPE_CLOSED`);let p={...u.value.envelope,...o.otp?{otp:!0}:{}},v=ui(p,`admin`,o.createdBy),y=[{...v,data:{...v.data,source:`bulk`}},di(p,`admin`,o.createdBy)];g.chunks.push(...u.value.chunks),g.signers.push(u.value.signer),g.envelopes.push({id:i,data:p}),g.audit.push(...await mr(i,y,a)),g.mail.push({id:Ws(u.value.signer.id),data:Gs(Zn({to:e.email,signerName:e.name,title:p.title,sender:_,link:`${d}/sign/${l}`,expiresAt:p.expiresAt}),r)}),m.set(e.seq,{seq:e.seq,status:`sent`,envelopeId:i})}));let v=z(e),y=async(e,t)=>{t.length>0&&await e.putMany(t)};await y(v.snapshots,g.chunks),await y(v.signers,g.signers),await y(v.envelopes,g.envelopes),await y(v.audit_events,g.audit),await y(er(e),g.mail);let b=s.rows.map(e=>m.get(e.seq)??e),x=[...m.values()].filter(e=>e.status===`sent`).length,S=[{id:t,data:{...o,sent:o.sent+x,failed:o.failed+h.length,failures:[...o.failures,...h].slice(0,50),status:l?`done`:`running`,updatedAt:c}},{id:oo(t,n),data:{...s,rows:b}}];return await i.putMany(S),l?await i.deleteMany([so(t)]):await u(),`sent`}async function dl(e,t,n=Date.now()){let r=po(e.name);return r?(await ul(t,r.jobId,r.page,n),!0):!1}const fl=`expire`,pl=`expire-more`;async function ml(e,t){if(e.name!==fl&&e.name!==pl)return!1;let{envelopes:n}=z(t),r=M(),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 Sa(t,e,i.value,{type:`envelope.expired`,at:r,actor:`system`})}return i.hasMore&&await t.cron?.schedule(pl,{schedule:M(Date.now()+6e4)}),!0}function hl(e){if(typeof e!=`string`)return null;let t=new TextEncoder().encode(e.trim());return t.length>=32?t:null}const gl=`intent-finish-`,_l=e=>`${gl}${e}`;function vl(e,t,n){return e?.schedule(_l(t),{schedule:M(n),data:{envelopeId:t}})}async function yl(e,t){let n=await ne(e),r=await crypto.subtle.sign(`HMAC`,n,new TextEncoder().encode(`esign-invite/1.${t}`));return T(new Uint8Array(r))}async function bl(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=z(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=qr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=hl(f.integrationMasterKey);if(!m)return`skipped`;let h=await yl(m,t),g=await oi(t,c,p.value,{now:M(n),tokenHash:await A(h),expiryDays:ga(f.expiryDays)});if(!g.ok)return`skipped`;await a.putMany(g.value.chunks);let _=await ya(o,g.value.signer,h);await rr(e,{signerId:g.value.signer.id,envelope:g.value.envelope,token:_,senderSetting:f.senderName,now:n});let v=[ui(c,`integration`),di(g.value.envelope,`integration`)];return await s.putMany(await mr(t,v,c.piiSalt)),(await I(r,t,`draft`,`sent`,g.value.envelope)).ok?`sent`:`skipped`}async function xl(e,t){if(!e.name.startsWith(gl))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await bl(t,n,Date.now()),!0}const Sl=`nonce-sweep`,Cl=`nonce-sweep-more`;async function wl(e){let{nonces:t,cron:n,now:r,page:i=100,pages:a=3}=e,o=M(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(Cl,{schedule:M(r+6e4)}),{deleted:s,more:c}}async function Tl(e,t){if(e.name!==Sl&&e.name!==Cl)return!1;let n=t.storage.nonces;return await wl({nonces:n,cron:t.cron,now:Date.now()}),!0}const El=`retention`,Dl=`retention-more`,Ol=`cron:retention`,kl=e=>e.status===`sent`||e.status===`in_progress`,Al=e=>kl(e)?null:Date.parse(e.completedAt??e.closedAt??e.updatedAt),jl=(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 Ml(e,t){let n=new Date(t);n.setUTCMonth(n.getUTCMonth()-jl(e,`retentionPersonalDataMonths`,12,120));let r=new Date(t);return r.setUTCFullYear(r.getUTCFullYear()-jl(e,`retentionSignedRecordsYears`,7,50)),{p:Math.max(n.getTime(),r.getTime()),r:r.getTime()}}function Nl(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 Pl(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 Fl(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:xr(e.data)}))),o.length>0&&await e.audit_events.deleteMany(o),i.hasMore?i.cursor:void 0}async function Il(e,t,n){let r=M(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:Nl(e,t)}]:[]});s.length>0&&await e.signers.putMany(s),i.length>0&&await e.envelopes.putMany(i.map(e=>({id:e.id,data:Pl(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 Ll(e,t){let n=z(e),r={...await e.kv.get(Ol)},i=!1;if(!r.phase||r.phase===`rl`)(await Sn(e.kv,t,3)).more?r.phase=`rl`:Object.assign(r,Ml(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:M(i)}},limit:10,...r.cursor?{cursor:r.cursor}:{}}),o=t=>e?t.personalPurgedAt:t.recordsPurgedAt,s=a.items.filter(({data:e})=>!o(e)&&(Al(e)??i)<i),c=s.length===0;if(!r.step&&s.length>0){if(e)r.acursor=await Fl(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 Il(n,s,t);else{let e=s.flatMap(e=>e.data.signerIds);e.length>0&&await n.signers.deleteMany(e);let r=M(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??M(i),delete r.cursor,delete r.keep,r.phase=e?`records`:`outbox`)}}return i&&delete r.phase,await e.kv.set(Ol,r),i||await e.cron?.schedule(Dl,{schedule:M(t)}),i}async function Rl(e,t,n=Date.now()){return e.name!==El&&e.name!==Dl?!1:(await Ll(t,n),!0)}const zl=e=>kl(e)||e.status===`completed`&&!e.pdfSha256;async function Bl(e,t){let n=z(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=>!zl(e.data)&&!e.data.personalPurgedAt),open:r.filter(e=>zl(e.data)).length}}async function Vl(e,t,n){let r=z(e),i=await Fl(r,t.due);if(i&&=await Fl(r,t.due,i),i)throw Error(`audit trail too long for one request`);await Il(r,t.due,n),await r.outbox.deleteMany(t.due.flatMap(e=>[`complete-${e.id}`,...e.data.signerIds.map(e=>`invite-${e}`)]))}const Hl=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Ul(e=te){return T(e(32))}const Wl=e=>hl(e)===null;function Gl(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:`&&Hl.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 Kl(e,t,n){let r=hl(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=Lt(n.random),o={name:i,clientId:a,createdAt:n.now,lastUsedAt:null,revokedAt:null,returnUrlAllowlist:t.returnUrlAllowlist};return await e.put(a,o),{ok:!0,client:o,pairing:Ft(a,await It(r,a))}}async function ql(e,t,n){return(await e.updateIf(t,{where:{revokedAt:null},set:{revokedAt:n}})).applied}async function Jl(e){return(await e.query({orderBy:{createdAt:`desc`},limit:100})).items.map(e=>e.data)}function Yl(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 Xl(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 Zl=e=>e.storage.templates,Ql=e=>({...se(`BAD_REQUEST`).body,...e?{issues:e}:{}}),$l=()=>se(`TEMPLATE_NOT_FOUND`).body;function eu(e){let t=B(e).id;return typeof t==`string`&&t.length>0&&t.length<=200&&!t.includes(`:`)?t:null}const tu=(e,t)=>({id:e,...t}),nu=(e,{body:t,...n})=>({id:e,...n});async function ru(e,t){let n=await Zl(e).get(t);return n&&n.status!==`version`?n:null}const iu={"templates/create":{handler:(async(e,t)=>{let n=crypto.randomUUID(),r=jr(e.input,{id:n,now:M()});if(!r.ok)return Ql(r.error);let{head:i,versions:a}=r.value;return await Zl(t).putMany([{id:n,data:i},...a]),{ok:!0,template:tu(n,i)}})},"templates/update":{handler:(async(e,t)=>{let n=eu(e.input);if(!n)return Ql();let r=await ru(t,n);if(!r)return $l();let i=Mr(r,e.input,{id:n,now:M()});return i.ok?(await Zl(t).putMany([{id:n,data:i.value.head},i.value.version]),{ok:!0,template:tu(n,i.value.head)}):Ql(i.error)})},"templates/get":{handler:(async(e,t)=>{let n=eu(e.input);if(!n)return Ql();let r=B(e.input).version;if(r!==void 0&&!(Number.isSafeInteger(r)&&r>=1))return Ql();let i=r,a=await Zl(t).getMany(i===void 0?[n]:[n,L(n,i)]),o=a.get(n);if(!o||o.status===`version`)return $l();let s=i===void 0?o:a.get(L(n,i));if(!s)return $l();let c=Array.from({length:o.version},(e,t)=>t+1);return{ok:!0,template:tu(n,{...s,status:o.status}),versions:c}})},"templates/list":{handler:(async(e,t)=>{let n=B(e.input).status??`active`;if(n!==`active`&&n!==`archived`)return Ql();let{items:r}=await Zl(t).query({where:{status:n},limit:200});return{ok:!0,templates:r.map(e=>nu(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=eu(e.input);if(!n)return Ql();let r=await ru(t,n);if(!r)return $l();if(r.status===`archived`)return{ok:!0,template:tu(n,r)};let i=Nr(r,M());return await Zl(t).putMany([{id:n,data:i}]),{ok:!0,template:tu(n,i)}})}},au=(e,t)=>({severity:`error`,title:e,...t?{message:t}:{}}),ou=e=>z(e.ctx).clients;async function su(e){return(await e.ctx.settings.list()).find(e=>e.key===`integrationMasterKey`)?.value}const cu=e=>typeof e==`string`&&e.trim()!==``;function lu(e,t,n=[]){let r=hl(e)!==null,o=typeof e==`object`&&!!e,s=Yl(null).banner;return q([i(`Integrations`),...h([o&&s&&{severity:`error`,title:`Encryption key missing`,message:s.message},!r&&!o&&{severity:`warning`,title:cu(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.`}]),...n,...r||o||cu(e)?[]:[g([_(`integrations.generate-key`,`Generate master key`,{style:`primary`})])],i(`Clients`),l({columns:[c(`name`,`Name`),c(`clientId`,`Client id`),c(`created`,`Created`,`relative_time`),c(`status`,`Status`,`badge`),c(`revoke`,``,`element`)],rows:t.map(e=>({name:e.name,clientId:e.clientId,created:e.createdAt,status:e.revokedAt?`Revoked`:`Active`,...e.revokedAt?{}:{revoke:_(`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.`}),a(`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).`),i(`Add a client`),a(`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.`),w({fields:[y(`name`,`Name`,{initialValue:``}),y(`returnUrlAllowlist`,`Allowed return URLs`,{multiline:!0,initialValue:``})],submit:{label:`Create client`,actionId:`client.create`}})])}async function uu(e,t,n=[]){return lu(t,await Jl(ou(e)),n)}async function du(e){let[t,n]=await Promise.all([su(e),Jl(ou(e))]);return lu(t,n)}async function fu(e){let t=await su(e);if(cu(t))return uu(e,t,h([au(`Key already set`,`Changing it would re-pair every client.`)]));let n=Ul();try{await e.ctx.settings.set(`integrationMasterKey`,n)}catch(n){if(!Xl(n))throw n;return uu(e,t,h([au(`Encryption key missing`,Yl(null).banner?.message)]))}return uu(e,n,h([{severity:`info`,title:`Master key generated`}]))}async function pu(e,t){let n=await su(e),r=(e,t)=>typeof e==`string`?e.slice(0,t):``,i=Gl(r(t.returnUrlAllowlist,2e3));if(!i.ok)return uu(e,n,h([au(`Not created`,`Return URL not allowed: ${i.entry.slice(0,200)}`)]));let a=await Kl(ou(e),{name:r(t.name,200),returnUrlAllowlist:i.entries,masterKey:n},{now:M(e.now)});return a.ok?uu(e,n,[...h([{severity:`warning`,title:`Copy the pairing string now`,message:`It is shown only this once and cannot be recovered. Treat it like a password.`}]),d({code:a.pairing})]):uu(e,n,h([au(`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 mu(e,t){let n=await ql(ou(e),t,M(e.now));return uu(e,await su(e),h([n?{severity:`info`,title:`Client revoked`}:au(`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),hu=e=>ja[e],gu=e=>iu[e],_u={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 vu(e,t=`The change was refused.`){let n=Array.isArray(e.issues)?e.issues:[];return n.length>0?n.map(e=>_u[e.code??``]??`${e.path??`input`} (${e.code??`invalid`})`).join(` `):e.error?.message??t}const yu=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),X=(e,t)=>yu(`error`,e,t),bu=(e,t)=>yu(`warning`,e,t),xu=(e,t)=>_(e,t,{style:`secondary`}),Z=(e,t)=>yu(`info`,e,t),Su=()=>xu(`envelopes.back`,`Back to envelopes`),Cu=()=>xu(`templates.back`,`Back to templates`),wu=e=>_(`envelope.open`,`Open envelope`,{value:e}),Tu={"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`},Eu=e=>!F(e.ctx)&&bu(`Set the site URL`,nr);async function Du(e){let t=await or(e.ctx);return[Eu(e),t.state===`no_transport`&&bu(`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&&bu(`${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 Ou(e,t,n=[],r){let o=Er(t)?t:``,[s,u]=await Promise.all([Y(e,hu(`envelopes/list`),{...o?{status:o}:{},...r?{cursor:r}:{}}),Du(e)]),d=typeof s.nextCursor==`string`?s.nextCursor:void 0,f=(s.envelopes??[]).map(e=>{let t=e.signer;return{title:e.title,signer:t?`${t.name??``} <${t.email??``}>`:``,status:e.status,created:e.createdAt,open:_(`envelope.open`,`Open`,{value:e.id})}});return q([i(`Envelopes`),...h(u),...n,w({fields:[x(`status`,`Status`,[{label:`Any status`,value:``},...Cr.map(e=>({label:e.replaceAll(`_`,` `),value:e}))],{initialValue:o})],submit:{label:`Filter`,actionId:`envelopes.filter`}}),a(`Newest first, 100 a page. Create an envelope from a template on the Templates page.`),l({columns:[c(`title`,`Title`),c(`signer`,`Signer`),c(`status`,`Status`,`badge`),c(`created`,`Created`,`relative_time`),c(`open`,``,`element`)],rows:f,pageActionId:`envelopes.page:${o}`,...d?{nextCursor:d}:{},emptyText:`No envelopes match.`}),i(ku),w({fields:[y(`subject`,`Signer email or envelope id`)],submit:{label:`Find`,actionId:`retention.preview`}})])}const ku=`Delete personal data`;async function Au(e,t,n){let r=await Bl(e.ctx,t),a=r.due.length;return n&&a>0&&await Vl(e.ctx,r,e.now),q([i(ku),...h([{severity:n?`info`:`warning`,title:n&&a>0?`Personal data deleted`:a+r.open>0?`${a} envelope(s) to delete, ${r.open} kept for now`:`No envelopes found`,message:`Signed records stay for their own period; open envelopes and pending PDFs are skipped.`}]),g([...!n&&a>0?[_(`retention.erase`,ku,{style:`danger`,value:t,confirm:{title:`${ku}?`,text:`This cannot be undone.`,confirm:`Delete`,deny:`Keep`,style:`danger`}})]:[],Su()])])}async function ju(e,t){if(!t)return`missing`;let n=await z(e.ctx).outbox.get(`invite-${t}`);return n?n.status===`failed`?`failed`:`queued`:`missing`}async function Mu(e,t,n={}){let{envelopes:r,signers:s,audit_events:u}=z(e.ctx),d=n.envelope??await r.get(t);if(!d)return q([i(`Envelope`),...h([X(`Envelope not found`,`It may have been removed.`)]),g([Su()])]);let f=d.status===`sent`||d.status===`in_progress`,[p,m,y]=await Promise.all([u.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:200}),n.signers?Promise.resolve(n.signers):d.signerIds.length>0?s.getMany(d.signerIds).then(e=>[...e].map(([e,t])=>({id:e,name:t.name,email:t.email,status:t.status}))):Promise.resolve([]),n.invite??(d.status===`sent`?ju(e,d.signerIds[0]):Promise.resolve(`n/a`))]),b=m[0],x=d.status===`sent`&&(y===`missing`||y===`failed`),S=null;if(d.status===`completed`&&!d.recordsPurgedAt)if(d.pdfSha256){let n=await la(e.ctx,t,e.now);S=g([v(`Download signed PDF`,{kind:`external`,url:`${e.origin}${n.url}`},{appearance:`primary`})])}else S=a(`The signed PDF is still being prepared. Reload in a minute.`);let C=[d.status===`draft`&&_(`envelope.send`,`Send for signature`,{style:`primary`,value:t}),x&&_(`envelope.resend`,`Resend invitation`,{style:`primary`,value:t}),(d.status===`draft`||f)&&_(`envelope.void`,`Void`,{style:`danger`,value:t,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`}}),Su()].filter(e=>e!==!1);return q([i(d.title),...h([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&&Eu(e)]),...n.extra??[],...d.personalPurgedAt?[a(`Personal data deleted ${d.personalPurgedAt}${d.recordsPurgedAt?`; signed records deleted`:``} (retention).`)]:[],o([{label:`Status`,value:d.status.replaceAll(`_`,` `)},{label:`Template`,value:`${d.templateId} v${d.templateVersion}`},{label:`Signer`,value:b?`${b.name} <${b.email}>`:d.signer.email},{label:`Signer status`,value:b?.status??`not sent yet`},{label:`Delivery`,value:d.delivery},{label:`Created`,value:d.createdAt},{label:`Sent`,value:d.sentAt??`Not sent`},{label:`Expires`,value:d.expiresAt??`Not set`},{label:`Completed`,value:d.completedAt??`Not completed`},{label:`Document SHA-256`,value:d.docSha256??`Set when sent`},{label:`Final hash`,value:d.finalHash??`Set when completed`}]),...S?[S]:[],g(C),i(`Audit timeline`),l({columns:[c(`seq`,`#`,`number`),c(`event`,`Event`),c(`at`,`When`,`text`),c(`actor`,`By`)],rows:p.items.map(({data:e})=>({seq:e.seq,event:Tu[e.type]??e.type,at:e.at,actor:e.actor})),pageActionId:`audit.page:${t}`,emptyText:`No events yet.`})])}async function Nu(e,t){let n;try{n=await Y(e,hu(`envelopes/send`),{id:t})}catch{return q([i(`Envelope`),...h([X(`The envelope was sent but the invitation could not be queued`,`Open the envelope and use Resend invitation.`)]),g([wu(t)])])}if(n.ok!==!0)return q([i(`Envelope`),...h([X(`Not sent`,vu(n))]),g([wu(t),Su()])]);let r=n.invitation===`SITE_URL_MISSING`;return q([i(`Envelope`),...h([r?{severity:`warning`,title:`Envelope sent, but no invitation was queued`,message:nr}:Z(`Envelope sent`,`The signer's invitation is queued.`)]),g([wu(t),Su()])])}async function Pu(e,t){let n=await Y(e,hu(`envelopes/void`),{id:t});if(n.ok!==!0){let r=n.error?.code===`ENVELOPE_CLOSED`;return Mu(e,t,{extra:h([X(r?`This envelope cannot be voided`:`Not voided`,r?`It is already completed, declined, voided or expired.`:vu(n))])})}return Mu(e,t,{envelope:n.envelope,invite:`n/a`,extra:h([Z(`Voided`,`The signer can no longer sign this envelope.`)])})}async function Fu(e,t){let n=await Y(e,hu(`envelopes/resend`),{id:t});return n.ok===!0?Mu(e,t,{envelope:n.envelope,invite:`queued`,signers:n.signers,extra:h([Z(`Invitation queued`,`A new email with a new signing link is on its way.`)])}):Mu(e,t,{extra:h([n.error?.code===`INVITATION_QUEUED`?Z(`Already queued`,`The invitation is queued or was sent.`):X(`Not resent`,vu(n,`Only an envelope that is sent and unsigned can be resent.`))])})}const Iu=/^(signer|participant)\./;async function Lu(e,t,n=[]){let r=await Y(e,gu(`templates/get`),{id:t}),o=r.template;return r.ok!==!0||!o?q([i(`New envelope`),...h([X(`Template not found`)]),...n]):q([i(`New envelope: ${o.name}`),...n,a(`Creates a draft you can check before sending it for signature. Signer fields: one per line as key: Label, ending in * when required.`),w({fields:[y(`title`,`Title`,{initialValue:o.name}),y(`signerName`,`Signer name`),y(`signerEmail`,`Signer email`),...o.fields.filter(e=>!Iu.test(e)).map(e=>y(`field:${e}`,e)),y(`signerFields`,`Fields the signer fills in (optional)`,{multiline:!0,placeholder:`phone: Phone number *`})],submit:{label:`Create draft`,actionId:`envelope.create`},blockId:`envelope-new:${t}`}),g([Cu()])])}function Ru(e){return typeof e==`string`?e.slice(0,4e3).split(`
|
|
53
|
-
`).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 zu(e,t,n){let r=t?.startsWith(`envelope-new:`)?t.slice(13):``;if(!r)return q(h([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=J(n.title),o=Ru(n.signerFields),s=await Y(e,hu(`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 Lu(e,r,h([X(`Not saved`,vu(s))]));let c=s.envelope.id;return Mu(e,c,{extra:h([Z(`Draft created`,`Check the details, then send it.`)])})}async function Bu(e,t=[]){let n=((await Y(e,gu(`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:_(`template.edit`,`Edit`,{value:e.id}),use:_(`envelope.new`,`New envelope`,{style:`primary`,value:e.id})}));return q([i(`Templates`),...t,l({columns:[c(`name`,`Name`),c(`id`,`ID`),c(`version`,`Version`,`number`),c(`fields`,`Fields`),c(`integrations`,`Integrations`),c(`updated`,`Updated`,`relative_time`),c(`edit`,``,`element`),c(`use`,``,`element`)],rows:n,pageActionId:`templates.page`,emptyText:`No templates yet. Add one below.`}),i(`New template`),a(`Write the document in Markdown. Use {{field}} for values filled in per envelope, and {{signer.name}} for the signer.`),w({fields:[y(`name`,`Name`),y(`description`,`Description (optional)`),y(`body`,`Template text`,{multiline:!0}),Vu(!1)],submit:{label:`Create template`,actionId:`template.create`}})])}function Vu(e){return S(`integrations`,`Available to integrations`,{description:`Paired sites (such as Events) may send this template for signing.`,initialValue:e})}function Hu(e){let t=Object.fromEntries(Fn(e).map(e=>[e,`«${e}»`]));try{return In(e,t)}catch{return e}}function Uu(e,t,n=[]){let r=String(t.body??``),o=Fn(r);return q([i(`Edit template: ${String(t.name??``)}`),...n,a(`Version ${String(t.version??1)}. Saving writes a new version; sent envelopes keep the text they were sent with.`),a(`Template id:`),d({code:e}),w({fields:[y(`name`,`Name`,{initialValue:String(t.name??``)}),y(`description`,`Description (optional)`,{initialValue:String(t.description??``)}),y(`body`,`Template text`,{initialValue:r,multiline:!0}),Vu(t.integrations===!0)],submit:{label:`Save new version`,actionId:`template.save`},blockId:`template:${e}`}),i(`Preview`),a(o.length>0?`Fields: ${o.join(`, `)}. Placeholders show as «name».`:`This template has no fields.`),d({code:Hu(r)}),g([_(`envelope.new`,`New envelope from this template`,{style:`primary`,value:e}),_(`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`}}),Cu()])])}async function Wu(e,t,n=[]){let r=await Y(e,gu(`templates/get`),{id:t});return r.ok!==!0||!r.template?Bu(e,h([X(`Template not found`)])):Uu(t,r.template,n)}async function Gu(e,t){let n=await Y(e,gu(`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?Bu(e,h([Z(`Template created`)])):Bu(e,h([X(`Not saved`,vu(n))]))}async function Ku(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return q(h([X(`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,gu(`templates/update`),{id:r,...i});return a.ok===!0?Uu(r,a.template,h([Z(`Saved`)])):Uu(r,{...i,version:`?`},h([X(`Not saved`,vu(a))]))}async function qu(e,t){let n=await Y(e,gu(`templates/archive`),{id:t});return Bu(e,h([n.ok===!0?Z(`Template archived`):X(`Not archived`,vu(n))]))}const Ju=[{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`}],Yu=[{key:`turnstileSecretKey`,label:`Turnstile secret key`},{key:`integrationMasterKey`,label:`Integration master key`}],Xu=e=>typeof e==`string`&&e!==``?`readable`:typeof e==`object`&&e?`unreadable`:`unset`;function Zu(e,t,n=[]){let r=Yu.some(e=>t[e.key]===`unreadable`),o=Yl(null).banner;return q([i(`Settings`),...h([r&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},t.integrationMasterKey===`unset`&&bu(`Integration master key not set`,`Other plugins cannot create envelopes through the integration protocol until it is saved.`)]),...n,w({fields:[...Ju.map(t=>t.kind===`number`?b(t.key,t.label,{min:t.min,max:t.max,...typeof e[t.key]==`number`?{initialValue:e[t.key]}:{}}):y(t.key,t.label,{multiline:t.kind===`long`,initialValue:typeof e[t.key]==`string`?e[t.key]:``})),...Yu.map(e=>C(e.key,`${e.label} (leave blank to keep)`,{hasValue:t[e.key]===`readable`}))],submit:{label:`Save settings`,actionId:`settings.save`}}),a(`Reminder and one-time-code settings (Pro) are in the plugin's own settings panel.`)])}async function Qu(e){let t=await e.ctx.settings.list(),n=Object.fromEntries(t.map(e=>[e.key,e.value]));return{values:n,secrets:Object.fromEntries(Yu.map(e=>[e.key,Xu(n[e.key])]))}}async function $u(e){let{values:t,secrets:n}=await Qu(e);return Zu(t,n)}async function ed(e,t){let{values:n,secrets:r}=await Qu(e),i=[],a=[];for(let e of Ju){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=Yu.filter(e=>J(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Wl(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 Zu(n,r,h([X(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return Zu(n,r,h([X(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return Zu(n,r,h([Z(`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(!Xl(e))throw e;let t=Yl(null).banner;return Zu(n,r,h([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return Zu(s,c,h([Z(`Saved`)]))}const td=e=>J(e,200);async function nd(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return Ou(e,``);case`/templates`:return Bu(e);case`/settings`:return $u(e);case`/integrations`:return du(e);default:return q(h([X(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return Ou(e,J(n.status));case`envelope.create`:return zu(e,t.block_id,n);case`template.create`:return Gu(e,n);case`template.save`:return Ku(e,t.block_id,n);case`settings.save`:return ed(e,n);case`client.create`:return pu(e,n);case`retention.preview`:return Au(e,J(n.subject),!1)}}else{let n=td(t.value);if(t.action_id.startsWith(`envelopes.page:`))return Ou(e,t.action_id.slice(15),[],J(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return Mu(e,td(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return Ou(e,``);case`envelope.open`:return Mu(e,n);case`envelope.send`:return Nu(e,n);case`envelope.void`:return Pu(e,n);case`envelope.resend`:return Fu(e,n);case`retention.erase`:return Au(e,n,!0);case`envelope.new`:return Lu(e,n);case`integrations.generate-key`:return fu(e);case`client.revoke`:return mu(e,n);case`clients.page`:return du(e);case`templates.back`:case`templates.page`:return Bu(e);case`template.edit`:return Wu(e,n);case`template.archive`:return qu(e,n)}}return q(h([X(`Unknown action`)]))}const rd={admin:{handler:(async(e,t)=>{let n=`http://localhost`;try{n=new URL(e.request?.url??``).origin}catch{}return nd({ctx:t,origin:n,now:Date.now(),user:e.user??null},e.input)})}},id=[`completed`,`declined`,`voided`,`expired`],ad=e=>{if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:Math.floor(t/1e3)};function od(e,t){let{status:n,clientId:r,externalRef:i}=t;if(!id.includes(n)||!r||!i||t.docSha256===null)return;let a=n===`completed`,o=a?ad(t.completedAt):ad(t.closedAt)??ad(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 Je(`receipt`,s).ok?s:void 0}async function sd(e,t,n){let r=od(e,t);return r?ut(`receipt`,r,n):void 0}function cd(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function ld(e){let t={};return{settings:()=>t,async getClient(n){let[r,i]=await Promise.all([e.settings.list(),z(e).clients.get(n)]);t=Object.fromEntries(r.map(e=>[e.key,e.value]));let a=hl(t.integrationMasterKey);if(!(!a||!i))return{secret:await It(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:cd(i.returnUrlAllowlist)}}}}async function ud(e,t,n){let r=hl(n);if(!(!r||!t.clientId))return sd(e,t,await It(r,t.clientId))}async function dd(e,t,n=Date.now()){let r=await lt({token:B(e).request,now:n,getClient:ld(t).getClient});if(!r.ok)return H(r.error);let i=[],a;for(let e=0;e<3;e++){let e=await z(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=>Pr(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 fd=(e,t)=>dd(e.input,t),pd=[`sent`,`in_progress`];function md(e){let t=B(e).token;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}const hd=e=>({...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}});function gd(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}function _d(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=()=>xn(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),H(t.ok?`SIGNING_TOKEN_INVALID`:`RATE_LIMITED`)}}}async function vd(e,t){let{items:n}=await z(e).signers.query({where:{tokenHash:await A(t)},limit:1}),r=n[0];return r&&await me(t,r.data.tokenHash)?r:null}async function yd(e,t){let{items:n}=await z(e).signers.query({where:{copyTokenHash:await A(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await me(t,r.data.copyTokenHash)?r:null}const bd=e=>!!(e.returnUrl&&e.clientId),xd=(e,t)=>bd(t)?e.settings.get(`integrationMasterKey`):Promise.resolve(void 0);async function Sd(e,t,n){if(!t.returnUrl)return{};let r=await ud(e,t,n);return{returnUrl:t.returnUrl,...r?{receipt:r}:{}}}const Cd=(e,t)=>e.find(e=>e.key===t)?.value;async function wd(e,t){let n=await(t?e.settings.list():e.settings.list(`consent`)),r=(e,t)=>{let r=Cd(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 P(i),masterKey:Cd(n,`integrationMasterKey`)}}const Td=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t;async function Ed(e,t,n,r){let i=await I(z(e).envelopes,t,n.status,`expired`,{closedAt:r,updatedAt:r});return i.ok&&await Sa(e,t,i.value,{type:`envelope.expired`,at:r,actor:`system`}),H(`SIGNING_TOKEN_EXPIRED`)}const Dd=(e,t)=>e.signerIds.length>1?t.order:void 0;async function Od(e,t,n,r,i){let a=z(e).audit_events,o=i;for(let e=0;e<2;e++){if(o??=await hr(t,await _r(a,t),r,n),await vr(a,o))return o;o=void 0}throw Error(`audit chain contention`)}async function kd(e,t){if(gd(e.request))return H(`TOKEN_IN_QUERY`);let n=_d(t,e),r=md(e.input);if(r===null)return n.fail();if(await n.blocked())return H(`RATE_LIMITED`);let i=B(e.input).open===!0,{envelopes:a,snapshots:o}=z(t),s=await vd(t,r),c=s?null:await yd(t,r),l=s??c;if(!l)return n.fail();let u=await a.get(l.data.envelopeId);if(!u)return H(`ENVELOPE_NOT_FOUND`);if(c&&u.status!==`completed`)return n.fail();if(!pd.includes(u.status)||l.data.status!==`pending`){let e={ok:!0,state:`closed`,status:u.status,title:u.title,...c?{}:await Sd(l.data.envelopeId,u,await xd(t,u))};return u.status!==`completed`||l.data.status!==`signed`?e:u.pdfSha256?{...e,pdf:`ready`,download:await la(t,l.data.envelopeId,Date.now())}:{...e,pdf:`pending`}}let d=M();if(Td(u,d))return Ed(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),wd(t,!1)]),h=f&&!u.snapshot?``:ai([...p.values()]);if(h===null)return H(`INTERNAL`);let g=u.status,_=Dd(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 z(t).signers.updateIf(l.id,{where:{viewedAt:null},set:{viewedAt:d}})).applied),n){let n=qa(d,u.docSha256??``,hd(e),_);if(!(await gr(z(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.noDecline?{noDecline:!0}:{},...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 Ad(e,t,n){if(gd(e.request))return H(`TOKEN_IN_QUERY`);let r=_d(t,e),i=md(e.input);if(i===null)return r.fail();let a=Ha(e.input);if(!a.ok)return V(a.error);let{envelopes:o,signers:s,audit_events:c}=z(t),l=await vd(t,i);if(!l||l.data.status!==`pending`)return r.fail();let u=l.data.envelopeId,d=await o.get(u);if(!d)return H(`ENVELOPE_NOT_FOUND`);if(d.status===`sent`)return H(`SESSION_REQUIRED`);if(d.status!==`in_progress`||d.document&&!n)return H(`ENVELOPE_CLOSED`);let f=M();if(Td(d,f))return Ed(t,u,d,f);if(d.otp&&!l.data.otpVerifiedAt)return H(`OTP_REQUIRED`);if(d.docSha256===null||a.value.docSha256!==d.docSha256)return V([{path:`docSha256`,code:`DOC_CHANGED`}]);let p=await wd(t,bd(d));if(a.value.consentSha256!==p.sha256)return V([{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 V(g);let _=await Wa(d.docSha256,a.value.signature,{fieldValues:h,salt:d.piiSalt}),v=hd(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}):H(`ENVELOPE_CLOSED`);let b=Ja({at:f,docSha256:d.docSha256,consentVersion:p.version,consentSha256:p.sha256,signature:_,signerName:l.data.name,who:v}),x=await hr(u,await _r(c,u),b,d.piiSalt),S=await Sr(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 H(`ENVELOPE_CLOSED`);if(await s.updateIf(l.id,{where:{status:`pending`},set:y}),!await vr(c,x))throw Error(`audit chain contention`);return await ea(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await Sd(u,C.value,p.masterKey)}}async function jd(e,t){if(gd(e.request))return H(`TOKEN_IN_QUERY`);let n=_d(t,e),r=md(e.input);if(r===null)return n.fail();let i=Ua(B(e.input).reason);if(i===null)return V([{path:`reason`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o}=z(t),s=await vd(t,r);if(!s||s.data.status!==`pending`)return n.fail();let c=s.data.envelopeId,l=await a.get(c);if(!l)return H(`ENVELOPE_NOT_FOUND`);if(l.noDecline)return H(`DECLINE_NOT_ALLOWED`);if(!Dr(l.status,`declined`))return H(`ENVELOPE_CLOSED`);let u=M();if(Td(l,u))return Ed(t,c,l,u);let d=await I(a,c,l.status,`declined`,{closedAt:u,updatedAt:u});if(!d.ok)return H(`ENVELOPE_CLOSED`);let f=hd(e);return await o.updateIf(s.id,{where:{status:`pending`},set:{status:`declined`,declinedAt:u,...i===void 0?{}:{declineReason:i},...f}}),await Od(t,c,l.piiSalt,Ya({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Dd(l,s.data)})),{ok:!0,status:`declined`,...await Sd(c,d.value,await xd(t,d.value))}}const Md=e=>(t,n)=>e(t,n),Nd=e=>({"public/session":Md(kd),"public/submit":Md((t,n)=>Ad(t,n,e)),"public/decline":Md(jd)}),Pd=Nd(),Fd=[`sent`,`in_progress`];function Id(e){try{return new URL(e.site.url).origin}catch{return}}async function Ld(e,t,n={}){let r=(n.now??Date.now)(),i=M(r),{envelopes:a,signers:o,snapshots:s,templates:c,nonces:l}=z(t),u=ld(t),d=await ot({token:B(e).intent,now:r,getClient:u.getClient,consumeNonce:async(e,t,n)=>{let r=`${e}.${t}`;try{let t={nonce:r,cid:e,expiresAt:M(n*1e3)};return(await l.compareAndSet(r,null,t)).applied}catch(e){if(_a(e))return!1;throw e}},siteOrigin:Id(t)});if(!d.ok)return H(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return Hd(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(!Pr(g))return H(`TEMPLATE_NOT_FOUND`);let _=qr(g,m===void 0?void 0:h.get(m),f.tplVersion);if(!_.ok)return H(`TEMPLATE_NOT_FOUND`);let v=cr(n.random),y=Qr(f,_.value,{now:i,piiSalt:v});if(!y.ok)return V(y.error);let b={delivery:y.value.delivery,signer:y.value.signer},x=f.resend===!0?(e,n,i)=>rr(t,{signerId:e,envelope:n,token:i,senderSetting:p.senderName,now:r}):void 0,S=ga(p.expiryDays),C=$r(f),ee=async(e,t,r)=>Vd(o,e,await Bd(a,e,t,C,S,i),b,n.random,r),w=k(n.random),te=await A(w),T=async e=>{let t=await li(f.cid,f.ref,e);return{id:t,sent:await oi(t,y.value,_.value,{now:i,tokenHash:te,expiryDays:S})}},E=await T(1);if(!E.sent.ok)return Array.isArray(E.sent.error)?V(E.sent.error):H(`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=ci(e.items);if(n)return n.data.status===`draft`&&await vl(t.cron,n.id,r),ee(n.id,n.data,x);let i=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await li(f.cid,f.ref,i);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?ee(e,t):H(`INTERNAL`)}return await vl(t.cron,e,r),Rd(e,y.value,void 0)}if(E=await T(i),!E.sent.ok)return Array.isArray(E.sent.error)?V(E.sent.error):H(`INTERNAL`);if(ne=await a.compareAndSet(E.id,null,E.sent.value.envelope),!ne.applied){let e=await a.get(E.id);return e?ee(E.id,e):H(`INTERNAL`)}}let{id:D,sent:O}=E;if(!O.ok)return H(`INTERNAL`);await s.putMany(O.value.chunks);let re=await ya(o,O.value.signer,w,n.random);O.value.envelope.delivery===`email`&&await rr(t,{signerId:O.value.signer.id,envelope:O.value.envelope,token:re,senderSetting:p.senderName,now:r});let ie=[ui(y.value,`integration`),di(O.value.envelope,`integration`)];return await z(t).audit_events.putMany(await mr(D,ie,v)),Rd(D,O.value.envelope,re)}function Rd(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function zd(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 Bd(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(Fd.includes(n.status)&&n.sentAt&&n.expiresAt){let s=ei(n.sentAt,i,r);s>n.expiresAt&&(o=await e.updateIf(t,{where:{status:{in:Fd},expiresAt:{lt:s}},set:{expiresAt:s,signBy:r,updatedAt:a}}))}return o.applied?o.data:n}async function Vd(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&zd(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 Rd(t,n,void 0);let u=await va(k(i),i,t=>e.updateIf(o,{where:{status:`pending`},set:{tokenHash:t}}));if(!u.value.applied)return Rd(t,n,void 0);if(c||!a)return Rd(t,n,u.token,!0);let d=await a(o,n,u.token);return{...Rd(t,n,void 0),...d?{resent:!0}:{}}}async function Hd(e,t,n){let{envelopes:r}=z(e),i=ci((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 Rd(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 Sa(e,i.id,o.value,{type:`envelope.voided`,at:n,actor:`integration`}),Rd(i.id,o.value,void 0)):H(`ENVELOPE_CLOSED`)}const Ud=(e,t)=>Ld(e.input,t),Wd=`integrations:site-client`,Gd=[`origin`,`sec-fetch-mode`,`sec-fetch-site`,`sec-fetch-dest`],Kd={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.`},qd=e=>({ok:!1,error:{code:e,message:Kd[e]}});function Jd(e,t){if(e)return typeof e.get==`function`?e.get(t)??void 0:e[t]}const Yd=e=>e!=null&&e!==``,Xd={"integrations/pair":{handler:(async(e,t)=>{let n=e.user?.role;if(typeof n!=`number`||n<50)return qd(`ADMIN_REQUIRED`);if(Gd.some(t=>Jd(e.request?.headers,t)!==void 0))return qd(`SERVER_ONLY`);let r=B(e.input),i=r.action;if(i!==`status`&&i!==`pair`&&i!==`unpair`)return qd(`BAD_REQUEST`);let a=r.clientId;if(a!==void 0&&(typeof a!=`string`||!Se.test(a)))return qd(`BAD_REQUEST`);let o=z(t).clients,[s,c]=await Promise.all([t.settings.list(),t.kv.get(Wd)]),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=M();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 ql(o,l,h),{ok:!0,revoked:p&&u?await ql(o,u,h):!1};let g=s.find(e=>e.key===`integrationMasterKey`)?.value;if(!Yd(g)){g=Ul();try{await t.settings.set(`integrationMasterKey`,g)}catch(e){if(Xl(e))return qd(`ENCRYPTION_KEY_MISSING`);throw e}}let _=hl(g);if(!_)return qd(`MASTER_KEY_INVALID`);let v=p&&u?u:m?l:null;if(v)return v!==l&&(await t.kv.set(Wd,v),m&&l&&await ql(o,l,h)),{ok:!0,created:!1,clientId:v,pairing:Ft(v,await It(_,v))};let y=await Kl(o,{name:`Events on this site`,returnUrlAllowlist:[],masterKey:g},{now:h});return y.ok?(await t.kv.set(Wd,y.client.clientId),{ok:!0,created:!0,clientId:y.client.clientId,pairing:y.pairing}):qd(`MASTER_KEY_INVALID`)})}},Zd=64*1024,Qd=[{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:Zd},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Zd}];async function $d(){return se({code:`NOT_FOUND`}).body}function ef(e={}){let t={};for(let n of Qd)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]??$d};return t}const tf=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function nf(e){let t;for(let n of e)(!t||tf(n.id)>tf(t.id)||tf(n.id)===tf(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function rf(e,t,n=Date.now()){let r=ld(t),i=await ct({token:B(e).request,now:n,getClient:r.getClient});if(!i.ok)return H(i.error);let{cid:a,ref:o}=i.value,s=nf((await z(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(!Or(s.data.status))return{ok:!0,state:`pending`,receipt:null};let c=await ud(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:H(`INTERNAL`)}const af=(e,t)=>rf(e.input,t),of=/^[0-9a-f]{64}$/,sf=async(e,t)=>{let n=B(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!of.test(r))return V([{path:`sha256`,code:`invalid`}]);if(!(await xn({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 H(`RATE_LIMITED`);let{envelopes:i,audit_events:a}=z(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 br(o.id,e);l=t.ok&&s.docSha256!==null&&e.at(-1)?.type===`envelope.completed`&&await Sr(s.docSha256,t.value.head)===s.finalHash}return{ok:!0,matched:!0,status:s.status,completedAt:s.completedAt,finalHash:s.finalHash,chainVerified:l}},cf=[{name:$n,schedule:`* * * * *`},{name:Sl,schedule:`0 * * * *`},{name:El,schedule:`23 3 * * *`},{name:fl,schedule:`17 * * * *`}],lf=ef({"public/envelopes/from-intent":Ud,"public/download":pa,"public/verify":sf,"public/receipts/lookup":af,"public/templates/catalog":fd,...Pd}),uf={hooks:{"plugin:activate":async(e,t)=>{await En(t,cf)},cron:async(e,t)=>{await On(e,t,cf,Date.now())||await ar(e,t)||await Ia(e,t)||await xl(e,t)||await Tl(e,t)||await Rl(e,t)||await ml(e,t)||await na(e,t)}},routes:{...lf,...rd,...iu,...ja,...Xd,admin:An(rd.admin,kn),"templates/create":An(iu[`templates/create`]),"public/verify":An(lf[`public/verify`])}},df={publicKey:`Trv2FjPQUPvm0izcO5IyqAZ5hse1-WShywKnN2s3ijg`,product:`esign`,buildDate:`2026-11-11`},ff=`esign-route-`,pf=e=>`${ff}${e}`;function mf(e,t,n,r=0){return e.cron?.schedule(pf(t),{schedule:M(n),data:{envelopeId:t,attempt:r}})}const hf=async(e,{envelopeId:t,envelope:n,signer:r,set:i,now:a})=>{let{signers:o}=z(e);if(n.routing===`sequential`&&r.data.order>1){let e=await o.getMany(n.signerIds);if(!Fs(`sequential`,r.data,[...e.values()]))return H(`SIGNING_OUT_OF_TURN`)}return(await o.updateIf(r.id,{where:{status:`pending`},set:i})).applied?(await mf(e,t,Date.parse(a)),{ok:!0,status:`in_progress`,signedAt:a}):H(`ENVELOPE_CLOSED`)};async function gf(e,t,n,r=0){let{envelopes:i,signers:a,audit_events:o}=z(e),s=await i.get(t);if(!s||s.signerIds.length<2||s.status===`completed`||s.personalPurgedAt)return`skipped`;let[c,l]=await Promise.all([a.getMany(s.signerIds),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),u=s.signerIds.flatMap(e=>{let t=c.get(e);return t?[{id:e,data:t}]:[]}),d=M(n),f=F(e),p=Bs(s,u,l.items.map(e=>e.data),d),m=f?p.invite:void 0,h=m||!p.invite?p.inputs:p.inputs.filter(e=>e.type!==`signer.invited`);if(h.length===0&&!m)return`idle`;if(l.hasMore)return e.log.error(`several-signer envelope has too many audit events to route`,{envelopeId:t}),`gave-up`;let g=await hr(t,l.items.at(-1)?.data??null,h,s.piiSalt),_=async()=>r+1>=5?(e.log.error(`several-signer envelope not routed: the chain never settled`,{envelopeId:t}),`gave-up`):(await mf(e,t,n+6e4,r+1),`retry`);if(p.complete){let r=await Sr(s.docSha256??``,g.at(-1)?.data.hash??``);if(!(await I(i,t,s.status,`completed`,{completedAt:d,finalHash:r,updatedAt:d})).ok)return _();if(!await vr(o,g))throw Error(`audit chain contention`);return await ea(e.cron,t,n),`completed`}return g.length>0&&!await vr(o,g)?_():m?(await _f(e,s,m,f,n),`invited`):`audited`}async function _f(e,t,n,r,i){let a=M(i),o=await e.settings.get(`senderName`),s=await va(k(),void 0,t=>z(e).signers.updateIf(n,{where:{status:`pending`,waiting:!0},set:{tokenHash:t,invitedAt:a,waiting:!1}}));if(!s.value.applied)return;let{email:c,name:l}=s.value.data;await er(e).put(Ws(n),Gs(Zn({to:c,signerName:l,title:t.title,sender:tr(e,o),link:`${r}/sign/${s.token}`,expiresAt:t.expiresAt}),i))}async function vf(e,t){if(!e.name.startsWith(ff))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n==`string`&&n.length>0&&await gf(t,n,Date.now(),typeof r==`number`&&Number.isSafeInteger(r)?r:0),!0}const yf=`reminders`,bf=`reminders-more`;function xf(e,t){let n=t.find(e=>e.status!==`signed`);return e.routing===`sequential`&&n?.waiting===!0&&Fs(`sequential`,n,t)}async function Sf(e,t,n,r){let i=F(e);if(!i)return;let a=await e.settings.list(),o=e=>a.find(t=>t.key===e)?.value,s=o(`licenceKey`);if(!le(await t.check({settings:{get:async()=>s},site:e.site}),`new`).ok)return;let c=Vs(o(`reminderCadenceDays`)),{envelopes:l,signers:u}=z(e),d=await l.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{gt:M(n)}},orderBy:{expiresAt:`asc`},limit:50,...r?{cursor:r}:{}}),f=d.items.filter(e=>Date.parse(e.data.sentAt??``)+c*864e5<=n),p=f.flatMap(e=>e.data.signerIds),m=p.length>0?await u.getMany(p):new Map,h=e=>e.data.signerIds.flatMap(e=>{let t=m.get(e);return t?[{id:e,data:t}]:[]}),[g,..._]=f.flatMap(e=>h(e).filter(t=>Hs(e.data,t.data,{now:n,cadenceDays:c})).map(t=>({envelope:e,signer:t})));if(g)await Cf(e,g.envelope,g.signer,i,o(`senderName`),n);else{let t=f.find(e=>xf(e.data,h(e).map(e=>e.data)));t&&await mf(e,t.id,n)}if(_.length>0||d.hasMore&&d.cursor){let t=_.length>0?r:d.cursor;await e.cron?.schedule(bf,{schedule:M(n+6e4),...t?{data:{cursor:t}}:{}})}}async function Cf(e,t,n,r,i,a){let{signers:o,audit_events:s}=z(e),c=M(a),l=(n.data.reminders??0)+1,u=await va(k(),void 0,e=>o.updateIf(n.id,{where:{status:`pending`,tokenHash:n.data.tokenHash},set:{tokenHash:e,remindedAt:c,reminders:l}}));if(!u.value.applied)return!1;if(await er(e).put(Ws(n.id),Gs(Us({to:n.data.email,signerName:n.data.name,title:t.data.title,sender:tr(e,i),link:`${r}/sign/${u.token}`,expiresAt:t.data.expiresAt}),a)),!(await gr(s,t.id,Ls(n.data,c,l),{salt:t.data.piiSalt})).ok)throw Error(`audit chain contention`);return!0}async function wf(e,t,n,r=Date.now()){if(e.name===wn)return await t.cron?.schedule(yf,{schedule:`29 * * * *`}),!1;if(e.name!==yf&&e.name!==bf)return!1;let i=e.name===bf?e.data?.cursor:void 0;return await Sf(t,n,r,typeof i==`string`&&i.length>0?i:void 0),!0}const Tf=`mcp-send-`,Ef=e=>(uf.routes??{})[e].handler,Df=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{},Of=()=>({ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}});async function kf(e,t){let{signers:n,routing:r,...i}=Df(e.input);if(!Array.isArray(n)||n.length<1||n.length>10)return V([{path:`signers`,code:`INVALID_SIGNERS`}]);if(n.length>1)return qs({...e,input:{...i,signers:n,routing:r??`parallel`}},t);if(!F(t))return Of();let a=await Ef(`envelopes/create`)({...e,input:{...i,signer:n[0]}},t);if(!a.envelope)return a;let o=e.user?.id;return await t.cron?.schedule(`${Tf}${a.envelope.id}`,{schedule:M(),data:{envelopeId:a.envelope.id,...typeof o==`string`?{userId:o}:{}}}),{...a,sending:!0}}async function Af(e,t){if(!e.name.startsWith(Tf))return!1;let n=e.data?.userId;return await Ef(`envelopes/send`)({input:{id:e.name.slice(9)},...typeof n==`string`?{user:{id:n}}:{}},t),!0}async function jf(e,t){let{snapshot:n,...r}=Df(await Ef(`envelopes/get`)(e,t));return r}async function Mf(e,t){let n=Df(e.input).id;if(typeof n!=`string`||n.length===0||n.length>100)return V([{path:`id`,code:`INVALID_INPUT`}]);let r=F(t);if(!r)return Of();let{envelopes:i,signers:a}=z(t),o=await i.get(n);if(!o)return H(`ENVELOPE_NOT_FOUND`);if(o.status!==`sent`&&o.status!==`in_progress`)return H(`ENVELOPE_CLOSED`);let s=Date.now(),c=await a.getMany(o.signerIds),[l,...u]=o.signerIds.flatMap(e=>{let t=c.get(e);return t&&Hs(o,t,{now:s,cadenceDays:.041666666666666664})?[{id:e,data:t}]:[]});return l?await Cf(t,{id:n,data:o},l,r,await t.settings.get(`senderName`),s)?{ok:!0,reminded:{signer:l.data.order},remaining:u.length}:{ok:!1,error:{code:`SIGNER_CHANGED`,message:`The signer's status changed. Try again.`}}:{ok:!1,error:{code:`NOTHING_TO_REMIND`,message:`No signer is due a reminder: each has signed, is not yet invited, was emailed in the last hour or has had the most reminders.`}}}const Nf=e=>({permission:`plugins:manage`,handler:e});function Pf(e){return{"pro/mcp/templates":Nf(Ef(`templates/list`)),"pro/mcp/send":e.gate(`esign/envelope-send`,Nf(kf)),"pro/mcp/status":Nf(jf),"pro/mcp/remind":e.gate(`new`,Nf(Mf)),"pro/mcp/void":Nf(Ef(`envelopes/void`))}}const Ff=[`sent`,`in_progress`],If=(e,t,n={})=>({ok:!1,error:{code:e,message:t,...n}}),Lf=(e,t)=>typeof e==`object`&&e?e[t]:void 0;function Rf(e){let t=Lf(e,`token`);return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function zf(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}async function Bf(e,t,n,r,i){return!(await xn({get:t=>e.kv.get(t),set:(t,n)=>e.kv.set(t,n)},t.requestMeta?.ip??`unknown`,i,{scope:n,limit:r,windowSeconds:600,salt:`esign-otp/1`})).ok}async function Vf(e,t,n){let{signers:r,envelopes:i}=z(e),a=(await r.query({where:{tokenHash:await A(t)},limit:1})).items[0];if(!a||a.data.status!==`pending`||!await me(t,a.data.tokenHash))return{error:H(`SIGNING_TOKEN_INVALID`)};let o=a.data.envelopeId,s=await i.get(o);return s?Ff.includes(s.status)?s.expiresAt!==null&&s.expiresAt<=n?{error:H(`SIGNING_TOKEN_EXPIRED`)}:s.otp?{signer:{id:a.id,data:a.data},envelope:s,envelopeId:o}:{error:If(`OTP_NOT_REQUIRED`,`This document does not need a code.`)}:{error:H(`ENVELOPE_CLOSED`)}:{error:H(`ENVELOPE_NOT_FOUND`)}}const Hf=e=>`Your code to sign: ${e.title}`,Uf=e=>`Your one-time code is ${e}\n\nIt expires in ${ho/6e4} minutes. Enter it on the signing page to continue. If you did not ask for it, ignore this email; nobody can sign for you without it. Never share this code.`;async function Wf(e,t){if(zf(e.request))return H(`TOKEN_IN_QUERY`);let n=Rf(e.input);if(n===null)return V([{path:`token`,code:`INVALID_INPUT`}]);let r=Date.now();if(await Bf(t,e,`otp-send`,10,r))return H(`RATE_LIMITED`);let i=await Vf(t,n,M(r));if(i.error)return i.error;let{signer:a,envelope:o}=i;if(a.data.otpVerifiedAt)return{ok:!0,sent:!1,verified:!0};let s=a.data.otp??void 0,c=bo(s,r);if(!c.ok)return c.code===`OTP_WAIT`?If(`OTP_WAIT`,`A code was sent a moment ago. Please wait before asking for another.`,{retryAfterSeconds:c.retryAfterSeconds}):H(`RATE_LIMITED`);let l=_o();await z(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:await xo(l,a.id,r,c),otpTries:0}});try{if(!t.email)throw Error(`no email`);await t.email.send({to:a.data.email,subject:Hf(o),text:Uf(l)})}catch{return await z(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:s??null,otpTries:a.data.otpTries??5}}),If(`OTP_SEND_FAILED`,`We could not email a code. Please try again shortly.`)}return{ok:!0,sent:!0,expiresInSeconds:ho/1e3}}async function Gf(e,t){if(zf(e.request))return H(`TOKEN_IN_QUERY`);let n=Rf(e.input),r=vo(Lf(e.input,`code`));if(n===null||r===null)return V([{path:n===null?`token`:`code`,code:`INVALID_INPUT`}]);let i=Date.now();if(await Bf(t,e,`otp-verify`,30,i))return H(`RATE_LIMITED`);let a=M(i),o=await Vf(t,n,a);if(o.error)return o.error;let{signer:s,envelope:c,envelopeId:l}=o;if(s.data.otpVerifiedAt)return{ok:!0,verified:!0};let{signers:u,audit_events:d}=z(t),f=s.data.otp??void 0,p=s.data.otpTries??5,m=await So(f&&{...f,attempts:p},r,s.id,i),h=()=>If(`OTP_LOCKED`,`Too many wrong codes. Ask for a new code.`);if(!m.ok&&m.code!==`OTP_INVALID`)return m.code===`OTP_EXPIRED`?If(`OTP_EXPIRED`,`That code has expired. Ask for a new code.`):h();if(!(await u.updateIf(s.id,{where:{status:`pending`,otpTries:{lt:5}},delta:{otpTries:{inc:1}}})).applied)return h();if(!m.ok)return If(`OTP_INVALID`,`That code is not right.`,{attemptsLeft:m.attemptsLeft});if(!(await gr(d,l,{type:`otp.verified`,at:a,actor:`signer`,data:{method:`email`,...Ka(c.signerIds.length>1?s.data.order:void 0)},personal:{...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}}},{salt:c.piiSalt})).ok)throw Error(`audit chain contention`);return await u.updateIf(s.id,{where:{status:`pending`,otpVerifiedAt:null},set:{otpVerifiedAt:a,otp:null}}),{ok:!0,verified:!0}}const Kf=/^[!-~]$/;function qf(e){let t=`/`;for(let n of e){let e=n.charCodeAt(0);t+=Kf.test(n)&&!`()<>[]{}/%#`.includes(n)?n:`#${(e&255).toString(16).padStart(2,`0`)}`}return t}function Jf(e){if(!Number.isFinite(e))return`0`;if(Number.isInteger(e))return String(e);let t=e.toFixed(6).replace(/0+$/,``).replace(/\.$/,``);return t===`-0`?`0`:t}function Q(e){if(e===null)return`null`;if(typeof e==`boolean`)return String(e);if(typeof e==`number`)return Jf(e);if(e instanceof jo)return qf(e.name);if(e instanceof No)return`${e.num} ${e.gen} R`;if(e instanceof Mo){let t=``;for(let n=0;n<e.bytes.length;n++)t+=e.bytes.charCodeAt(n).toString(16).padStart(2,`0`);return`<${t}>`}return Array.isArray(e)?`[${e.map(Q).join(` `)}]`:`<<${[...e].map(([e,t])=>`${qf(e)} ${Q(t)}`).join(` `)}>>`}const Yf=(e,t=``)=>`<< /Length ${e.length}${t} >>\nstream\n${e}\nendstream`;var Xf=class{objects=new Map;next;constructor(e){this.file=e,this.next=e.size}add(e){let t=new No(this.next++,0);return this.objects.set(t.num,{gen:0,body:e}),t}replace(e,t){this.objects.set(e.num,{gen:this.file.genOf(e.num),body:t})}bytes(){let{file:e}=this,t=e.bytes.length,n=e.bytes[t-1],r=n===10||n===13?``:`
|
|
53
|
+
`).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 zu(e,t,n){let r=t?.startsWith(`envelope-new:`)?t.slice(13):``;if(!r)return q(h([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=J(n.title),o=Ru(n.signerFields),s=await Y(e,hu(`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 Lu(e,r,h([X(`Not saved`,vu(s))]));let c=s.envelope.id;return Mu(e,c,{extra:h([Z(`Draft created`,`Check the details, then send it.`)])})}async function Bu(e,t=[]){let n=((await Y(e,gu(`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:_(`template.edit`,`Edit`,{value:e.id}),use:_(`envelope.new`,`New envelope`,{style:`primary`,value:e.id})}));return q([i(`Templates`),...t,l({columns:[c(`name`,`Name`),c(`id`,`ID`),c(`version`,`Version`,`number`),c(`fields`,`Fields`),c(`integrations`,`Integrations`),c(`updated`,`Updated`,`relative_time`),c(`edit`,``,`element`),c(`use`,``,`element`)],rows:n,pageActionId:`templates.page`,emptyText:`No templates yet. Add one below.`}),i(`New template`),a(`Write the document in Markdown. Use {{field}} for values filled in per envelope, and {{signer.name}} for the signer.`),w({fields:[y(`name`,`Name`),y(`description`,`Description (optional)`),y(`body`,`Template text`,{multiline:!0}),Vu(!1)],submit:{label:`Create template`,actionId:`template.create`}})])}function Vu(e){return S(`integrations`,`Available to integrations`,{description:`Paired sites (such as Events) may send this template for signing.`,initialValue:e})}function Hu(e){let t=Object.fromEntries(Fn(e).map(e=>[e,`«${e}»`]));try{return In(e,t)}catch{return e}}function Uu(e,t,n=[]){let r=String(t.body??``),o=Fn(r);return q([i(`Edit template: ${String(t.name??``)}`),...n,a(`Version ${String(t.version??1)}. Saving writes a new version; sent envelopes keep the text they were sent with.`),a(`Template id:`),d({code:e}),w({fields:[y(`name`,`Name`,{initialValue:String(t.name??``)}),y(`description`,`Description (optional)`,{initialValue:String(t.description??``)}),y(`body`,`Template text`,{initialValue:r,multiline:!0}),Vu(t.integrations===!0)],submit:{label:`Save new version`,actionId:`template.save`},blockId:`template:${e}`}),i(`Preview`),a(o.length>0?`Fields: ${o.join(`, `)}. Placeholders show as «name».`:`This template has no fields.`),d({code:Hu(r)}),g([_(`envelope.new`,`New envelope from this template`,{style:`primary`,value:e}),_(`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`}}),Cu()])])}async function Wu(e,t,n=[]){let r=await Y(e,gu(`templates/get`),{id:t});return r.ok!==!0||!r.template?Bu(e,h([X(`Template not found`)])):Uu(t,r.template,n)}async function Gu(e,t){let n=await Y(e,gu(`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?Bu(e,h([Z(`Template created`)])):Bu(e,h([X(`Not saved`,vu(n))]))}async function Ku(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return q(h([X(`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,gu(`templates/update`),{id:r,...i});return a.ok===!0?Uu(r,a.template,h([Z(`Saved`)])):Uu(r,{...i,version:`?`},h([X(`Not saved`,vu(a))]))}async function qu(e,t){let n=await Y(e,gu(`templates/archive`),{id:t});return Bu(e,h([n.ok===!0?Z(`Template archived`):X(`Not archived`,vu(n))]))}const Ju=[{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`}],Yu=[{key:`turnstileSecretKey`,label:`Turnstile secret key`},{key:`integrationMasterKey`,label:`Integration master key`}],Xu=e=>typeof e==`string`&&e!==``?`readable`:typeof e==`object`&&e?`unreadable`:`unset`;function Zu(e,t,n=[]){let r=Yu.some(e=>t[e.key]===`unreadable`),o=Yl(null).banner;return q([i(`Settings`),...h([r&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},t.integrationMasterKey===`unset`&&bu(`Integration master key not set`,`Other plugins cannot create envelopes through the integration protocol until it is saved.`)]),...n,w({fields:[...Ju.map(t=>t.kind===`number`?b(t.key,t.label,{min:t.min,max:t.max,...typeof e[t.key]==`number`?{initialValue:e[t.key]}:{}}):y(t.key,t.label,{multiline:t.kind===`long`,initialValue:typeof e[t.key]==`string`?e[t.key]:``})),...Yu.map(e=>C(e.key,`${e.label} (leave blank to keep)`,{hasValue:t[e.key]===`readable`}))],submit:{label:`Save settings`,actionId:`settings.save`}}),a(`Reminder and one-time-code settings (Pro) are in the plugin's own settings panel.`)])}async function Qu(e){let t=await e.ctx.settings.list(),n=Object.fromEntries(t.map(e=>[e.key,e.value]));return{values:n,secrets:Object.fromEntries(Yu.map(e=>[e.key,Xu(n[e.key])]))}}async function $u(e){let{values:t,secrets:n}=await Qu(e);return Zu(t,n)}async function ed(e,t){let{values:n,secrets:r}=await Qu(e),i=[],a=[];for(let e of Ju){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=Yu.filter(e=>J(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Wl(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 Zu(n,r,h([X(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return Zu(n,r,h([X(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return Zu(n,r,h([Z(`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(!Xl(e))throw e;let t=Yl(null).banner;return Zu(n,r,h([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return Zu(s,c,h([Z(`Saved`)]))}const td=e=>J(e,200);async function nd(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return Ou(e,``);case`/templates`:return Bu(e);case`/settings`:return $u(e);case`/integrations`:return du(e);default:return q(h([X(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return Ou(e,J(n.status));case`envelope.create`:return zu(e,t.block_id,n);case`template.create`:return Gu(e,n);case`template.save`:return Ku(e,t.block_id,n);case`settings.save`:return ed(e,n);case`client.create`:return pu(e,n);case`retention.preview`:return Au(e,J(n.subject),!1)}}else{let n=td(t.value);if(t.action_id.startsWith(`envelopes.page:`))return Ou(e,t.action_id.slice(15),[],J(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return Mu(e,td(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return Ou(e,``);case`envelope.open`:return Mu(e,n);case`envelope.send`:return Nu(e,n);case`envelope.void`:return Pu(e,n);case`envelope.resend`:return Fu(e,n);case`retention.erase`:return Au(e,n,!0);case`envelope.new`:return Lu(e,n);case`integrations.generate-key`:return fu(e);case`client.revoke`:return mu(e,n);case`clients.page`:return du(e);case`templates.back`:case`templates.page`:return Bu(e);case`template.edit`:return Wu(e,n);case`template.archive`:return qu(e,n)}}return q(h([X(`Unknown action`)]))}const rd={admin:{handler:(async(e,t)=>{let n=`http://localhost`;try{n=new URL(e.request?.url??``).origin}catch{}return nd({ctx:t,origin:n,now:Date.now(),user:e.user??null},e.input)})}},id=[`completed`,`declined`,`voided`,`expired`],ad=e=>{if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:Math.floor(t/1e3)};function od(e,t){let{status:n,clientId:r,externalRef:i}=t;if(!id.includes(n)||!r||!i||t.docSha256===null)return;let a=n===`completed`,o=a?ad(t.completedAt):ad(t.closedAt)??ad(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 Je(`receipt`,s).ok?s:void 0}async function sd(e,t,n){let r=od(e,t);return r?ut(`receipt`,r,n):void 0}function cd(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function ld(e){let t={};return{settings:()=>t,async getClient(n){let[r,i]=await Promise.all([e.settings.list(),z(e).clients.get(n)]);t=Object.fromEntries(r.map(e=>[e.key,e.value]));let a=hl(t.integrationMasterKey);if(!(!a||!i))return{secret:await It(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:cd(i.returnUrlAllowlist)}}}}async function ud(e,t,n){let r=hl(n);if(!(!r||!t.clientId))return sd(e,t,await It(r,t.clientId))}async function dd(e,t,n=Date.now()){let r=await lt({token:B(e).request,now:n,getClient:ld(t).getClient});if(!r.ok)return H(r.error);let i=[],a;for(let e=0;e<3;e++){let e=await z(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=>Pr(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 fd=(e,t)=>dd(e.input,t),pd=[`sent`,`in_progress`];function md(e){let t=B(e).token;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}const hd=e=>({...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}});function gd(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}function _d(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=()=>xn(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),H(t.ok?`SIGNING_TOKEN_INVALID`:`RATE_LIMITED`)}}}async function vd(e,t){let{items:n}=await z(e).signers.query({where:{tokenHash:await A(t)},limit:1}),r=n[0];return r&&await me(t,r.data.tokenHash)?r:null}async function yd(e,t){let{items:n}=await z(e).signers.query({where:{copyTokenHash:await A(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await me(t,r.data.copyTokenHash)?r:null}const bd=e=>!!(e.returnUrl&&e.clientId),xd=(e,t)=>bd(t)?e.settings.get(`integrationMasterKey`):Promise.resolve(void 0);async function Sd(e,t,n){if(!t.returnUrl)return{};let r=await ud(e,t,n);return{returnUrl:t.returnUrl,...r?{receipt:r}:{}}}const Cd=(e,t)=>e.find(e=>e.key===t)?.value;async function wd(e,t){let n=await(t?e.settings.list():e.settings.list(`consent`)),r=(e,t)=>{let r=Cd(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 P(i),masterKey:Cd(n,`integrationMasterKey`)}}const Td=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t;async function Ed(e,t,n,r){let i=await I(z(e).envelopes,t,n.status,`expired`,{closedAt:r,updatedAt:r});return i.ok&&await Sa(e,t,i.value,{type:`envelope.expired`,at:r,actor:`system`}),H(`SIGNING_TOKEN_EXPIRED`)}const Dd=(e,t)=>e.signerIds.length>1?t.order:void 0;async function Od(e,t,n,r,i){let a=z(e).audit_events,o=i;for(let e=0;e<2;e++){if(o??=await hr(t,await _r(a,t),r,n),await vr(a,o))return o;o=void 0}throw Error(`audit chain contention`)}async function kd(e,t){if(gd(e.request))return H(`TOKEN_IN_QUERY`);let n=_d(t,e),r=md(e.input);if(r===null)return n.fail();if(await n.blocked())return H(`RATE_LIMITED`);let i=B(e.input).open===!0,{envelopes:a,snapshots:o}=z(t),s=await vd(t,r),c=s?null:await yd(t,r),l=s??c;if(!l)return n.fail();let u=await a.get(l.data.envelopeId);if(!u)return H(`ENVELOPE_NOT_FOUND`);if(c&&u.status!==`completed`)return n.fail();if(!pd.includes(u.status)||l.data.status!==`pending`){let e={ok:!0,state:`closed`,status:u.status,title:u.title,...c?{}:await Sd(l.data.envelopeId,u,await xd(t,u))};return u.status!==`completed`||l.data.status!==`signed`?e:u.pdfSha256?{...e,pdf:`ready`,download:await la(t,l.data.envelopeId,Date.now())}:{...e,pdf:`pending`}}let d=M();if(Td(u,d))return Ed(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),wd(t,!1)]),h=f&&!u.snapshot?``:ai([...p.values()]);if(h===null)return H(`INTERNAL`);let g=u.status,_=Dd(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 z(t).signers.updateIf(l.id,{where:{viewedAt:null},set:{viewedAt:d}})).applied),n){let n=qa(d,u.docSha256??``,hd(e),_);if(!(await gr(z(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.noDecline?{noDecline:!0}:{},...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 Ad(e,t,n){if(gd(e.request))return H(`TOKEN_IN_QUERY`);let r=_d(t,e),i=md(e.input);if(i===null)return r.fail();let a=Ha(e.input);if(!a.ok)return V(a.error);let{envelopes:o,signers:s,audit_events:c}=z(t),l=await vd(t,i);if(!l||l.data.status!==`pending`)return r.fail();let u=l.data.envelopeId,d=await o.get(u);if(!d)return H(`ENVELOPE_NOT_FOUND`);if(d.status===`sent`)return H(`SESSION_REQUIRED`);if(d.status!==`in_progress`||d.document&&!n)return H(`ENVELOPE_CLOSED`);let f=M();if(Td(d,f))return Ed(t,u,d,f);if(d.otp&&!l.data.otpVerifiedAt)return H(`OTP_REQUIRED`);if(d.docSha256===null||a.value.docSha256!==d.docSha256)return V([{path:`docSha256`,code:`DOC_CHANGED`}]);let p=await wd(t,bd(d));if(a.value.consentSha256!==p.sha256)return V([{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 V(g);let _=await Wa(d.docSha256,a.value.signature,{fieldValues:h,salt:d.piiSalt}),v=hd(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}):H(`ENVELOPE_CLOSED`);let b=Ja({at:f,docSha256:d.docSha256,consentVersion:p.version,consentSha256:p.sha256,signature:_,signerName:l.data.name,who:v}),x=await hr(u,await _r(c,u),b,d.piiSalt),S=await Sr(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 H(`ENVELOPE_CLOSED`);if(await s.updateIf(l.id,{where:{status:`pending`},set:y}),!await vr(c,x))throw Error(`audit chain contention`);return await ea(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await Sd(u,C.value,p.masterKey)}}async function jd(e,t){if(gd(e.request))return H(`TOKEN_IN_QUERY`);let n=_d(t,e),r=md(e.input);if(r===null)return n.fail();let i=Ua(B(e.input).reason);if(i===null)return V([{path:`reason`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o}=z(t),s=await vd(t,r);if(!s||s.data.status!==`pending`)return n.fail();let c=s.data.envelopeId,l=await a.get(c);if(!l)return H(`ENVELOPE_NOT_FOUND`);if(l.noDecline)return H(`DECLINE_NOT_ALLOWED`);if(!Dr(l.status,`declined`))return H(`ENVELOPE_CLOSED`);let u=M();if(Td(l,u))return Ed(t,c,l,u);let d=await I(a,c,l.status,`declined`,{closedAt:u,updatedAt:u});if(!d.ok)return H(`ENVELOPE_CLOSED`);let f=hd(e);return await o.updateIf(s.id,{where:{status:`pending`},set:{status:`declined`,declinedAt:u,...i===void 0?{}:{declineReason:i},...f}}),await Od(t,c,l.piiSalt,Ya({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Dd(l,s.data)})),{ok:!0,status:`declined`,...await Sd(c,d.value,await xd(t,d.value))}}const Md=e=>(t,n)=>e(t,n),Nd=e=>({"public/session":Md(kd),"public/submit":Md((t,n)=>Ad(t,n,e)),"public/decline":Md(jd)}),Pd=Nd(),Fd=[`sent`,`in_progress`];function Id(e){try{return new URL(e.site.url).origin}catch{return}}async function Ld(e,t,n={}){let r=(n.now??Date.now)(),i=M(r),{envelopes:a,signers:o,snapshots:s,templates:c,nonces:l}=z(t),u=ld(t),d=await ot({token:B(e).intent,now:r,getClient:u.getClient,consumeNonce:async(e,t,n)=>{let r=`${e}.${t}`;try{let t={nonce:r,cid:e,expiresAt:M(n*1e3)};return(await l.compareAndSet(r,null,t)).applied}catch(e){if(_a(e))return!1;throw e}},siteOrigin:Id(t)});if(!d.ok)return H(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return Hd(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(!Pr(g))return H(`TEMPLATE_NOT_FOUND`);let _=qr(g,m===void 0?void 0:h.get(m),f.tplVersion);if(!_.ok)return H(`TEMPLATE_NOT_FOUND`);let v=cr(n.random),y=Qr(f,_.value,{now:i,piiSalt:v});if(!y.ok)return V(y.error);let b={delivery:y.value.delivery,signer:y.value.signer},x=f.resend===!0?(e,n,i)=>rr(t,{signerId:e,envelope:n,token:i,senderSetting:p.senderName,now:r}):void 0,S=ga(p.expiryDays),C=$r(f),ee=async(e,t,r)=>Vd(o,e,await Bd(a,e,t,C,S,i),b,n.random,r),w=k(n.random),te=await A(w),T=async e=>{let t=await li(f.cid,f.ref,e);return{id:t,sent:await oi(t,y.value,_.value,{now:i,tokenHash:te,expiryDays:S})}},E=await T(1);if(!E.sent.ok)return Array.isArray(E.sent.error)?V(E.sent.error):H(`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=ci(e.items);if(n)return n.data.status===`draft`&&await vl(t.cron,n.id,r),ee(n.id,n.data,x);let i=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await li(f.cid,f.ref,i);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?ee(e,t):H(`INTERNAL`)}return await vl(t.cron,e,r),Rd(e,y.value,void 0)}if(E=await T(i),!E.sent.ok)return Array.isArray(E.sent.error)?V(E.sent.error):H(`INTERNAL`);if(ne=await a.compareAndSet(E.id,null,E.sent.value.envelope),!ne.applied){let e=await a.get(E.id);return e?ee(E.id,e):H(`INTERNAL`)}}let{id:D,sent:O}=E;if(!O.ok)return H(`INTERNAL`);await s.putMany(O.value.chunks);let re=await ya(o,O.value.signer,w,n.random);O.value.envelope.delivery===`email`&&await rr(t,{signerId:O.value.signer.id,envelope:O.value.envelope,token:re,senderSetting:p.senderName,now:r});let ie=[ui(y.value,`integration`),di(O.value.envelope,`integration`)];return await z(t).audit_events.putMany(await mr(D,ie,v)),Rd(D,O.value.envelope,re)}function Rd(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function zd(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 Bd(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(Fd.includes(n.status)&&n.sentAt&&n.expiresAt){let s=ei(n.sentAt,i,r);s>n.expiresAt&&(o=await e.updateIf(t,{where:{status:{in:Fd},expiresAt:{lt:s}},set:{expiresAt:s,signBy:r,updatedAt:a}}))}return o.applied?o.data:n}async function Vd(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&zd(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 Rd(t,n,void 0);let u=await va(k(i),i,t=>e.updateIf(o,{where:{status:`pending`},set:{tokenHash:t}}));if(!u.value.applied)return Rd(t,n,void 0);if(c||!a)return Rd(t,n,u.token,!0);let d=await a(o,n,u.token);return{...Rd(t,n,void 0),...d?{resent:!0}:{}}}async function Hd(e,t,n){let{envelopes:r}=z(e),i=ci((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 Rd(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 Sa(e,i.id,o.value,{type:`envelope.voided`,at:n,actor:`integration`}),Rd(i.id,o.value,void 0)):H(`ENVELOPE_CLOSED`)}const Ud=(e,t)=>Ld(e.input,t),Wd=`integrations:site-client`,Gd=[`origin`,`sec-fetch-mode`,`sec-fetch-site`,`sec-fetch-dest`],Kd={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.`},qd=e=>({ok:!1,error:{code:e,message:Kd[e]}});function Jd(e,t){if(e)return typeof e.get==`function`?e.get(t)??void 0:e[t]}const Yd=e=>e!=null&&e!==``,Xd={"integrations/pair":{handler:(async(e,t)=>{let n=e.user?.role;if(typeof n!=`number`||n<50)return qd(`ADMIN_REQUIRED`);if(Gd.some(t=>Jd(e.request?.headers,t)!==void 0))return qd(`SERVER_ONLY`);let r=B(e.input),i=r.action;if(i!==`status`&&i!==`pair`&&i!==`unpair`)return qd(`BAD_REQUEST`);let a=r.clientId;if(a!==void 0&&(typeof a!=`string`||!Se.test(a)))return qd(`BAD_REQUEST`);let o=z(t).clients,[s,c]=await Promise.all([t.settings.list(),t.kv.get(Wd)]),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=M();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 ql(o,l,h),{ok:!0,revoked:p&&u?await ql(o,u,h):!1};let g=s.find(e=>e.key===`integrationMasterKey`)?.value;if(!Yd(g)){g=Ul();try{await t.settings.set(`integrationMasterKey`,g)}catch(e){if(Xl(e))return qd(`ENCRYPTION_KEY_MISSING`);throw e}}let _=hl(g);if(!_)return qd(`MASTER_KEY_INVALID`);let v=p&&u?u:m?l:null;if(v)return v!==l&&(await t.kv.set(Wd,v),m&&l&&await ql(o,l,h)),{ok:!0,created:!1,clientId:v,pairing:Ft(v,await It(_,v))};let y=await Kl(o,{name:`Events on this site`,returnUrlAllowlist:[],masterKey:g},{now:h});return y.ok?(await t.kv.set(Wd,y.client.clientId),{ok:!0,created:!0,clientId:y.client.clientId,pairing:y.pairing}):qd(`MASTER_KEY_INVALID`)})}},Zd=64*1024,Qd=[{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:Zd},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Zd}];async function $d(){return se({code:`NOT_FOUND`}).body}function ef(e={}){let t={};for(let n of Qd)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]??$d};return t}const tf=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function nf(e){let t;for(let n of e)(!t||tf(n.id)>tf(t.id)||tf(n.id)===tf(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function rf(e,t,n=Date.now()){let r=ld(t),i=await ct({token:B(e).request,now:n,getClient:r.getClient});if(!i.ok)return H(i.error);let{cid:a,ref:o}=i.value,s=nf((await z(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(!Or(s.data.status))return{ok:!0,state:`pending`,receipt:null};let c=await ud(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:H(`INTERNAL`)}const af=(e,t)=>rf(e.input,t),of=/^[0-9a-f]{64}$/,sf=async(e,t)=>{let n=B(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!of.test(r))return V([{path:`sha256`,code:`invalid`}]);if(!(await xn({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 H(`RATE_LIMITED`);let{envelopes:i,audit_events:a}=z(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 br(o.id,e);l=t.ok&&s.docSha256!==null&&e.at(-1)?.type===`envelope.completed`&&await Sr(s.docSha256,t.value.head)===s.finalHash}return{ok:!0,matched:!0,status:s.status,completedAt:s.completedAt,finalHash:s.finalHash,chainVerified:l}},cf=[{name:$n,schedule:`* * * * *`},{name:Sl,schedule:`0 * * * *`},{name:El,schedule:`23 3 * * *`},{name:fl,schedule:`17 * * * *`}],lf=ef({"public/envelopes/from-intent":Ud,"public/download":pa,"public/verify":sf,"public/receipts/lookup":af,"public/templates/catalog":fd,...Pd}),uf={hooks:{"plugin:activate":async(e,t)=>{await En(t,cf)},cron:async(e,t)=>{await On(e,t,cf,Date.now())||await ar(e,t)||await Ia(e,t)||await xl(e,t)||await Tl(e,t)||await Rl(e,t)||await ml(e,t)||await na(e,t)}},routes:{...lf,...rd,...iu,...ja,...Xd,admin:An(rd.admin,kn),"templates/create":An(iu[`templates/create`]),"public/verify":An(lf[`public/verify`])}},df={publicKey:`Trv2FjPQUPvm0izcO5IyqAZ5hse1-WShywKnN2s3ijg`,product:`esign`,buildDate:`2026-11-14`},ff=`esign-route-`,pf=e=>`${ff}${e}`;function mf(e,t,n,r=0){return e.cron?.schedule(pf(t),{schedule:M(n),data:{envelopeId:t,attempt:r}})}const hf=async(e,{envelopeId:t,envelope:n,signer:r,set:i,now:a})=>{let{signers:o}=z(e);if(n.routing===`sequential`&&r.data.order>1){let e=await o.getMany(n.signerIds);if(!Fs(`sequential`,r.data,[...e.values()]))return H(`SIGNING_OUT_OF_TURN`)}return(await o.updateIf(r.id,{where:{status:`pending`},set:i})).applied?(await mf(e,t,Date.parse(a)),{ok:!0,status:`in_progress`,signedAt:a}):H(`ENVELOPE_CLOSED`)};async function gf(e,t,n,r=0){let{envelopes:i,signers:a,audit_events:o}=z(e),s=await i.get(t);if(!s||s.signerIds.length<2||s.status===`completed`||s.personalPurgedAt)return`skipped`;let[c,l]=await Promise.all([a.getMany(s.signerIds),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),u=s.signerIds.flatMap(e=>{let t=c.get(e);return t?[{id:e,data:t}]:[]}),d=M(n),f=F(e),p=Bs(s,u,l.items.map(e=>e.data),d),m=f?p.invite:void 0,h=m||!p.invite?p.inputs:p.inputs.filter(e=>e.type!==`signer.invited`);if(h.length===0&&!m)return`idle`;if(l.hasMore)return e.log.error(`several-signer envelope has too many audit events to route`,{envelopeId:t}),`gave-up`;let g=await hr(t,l.items.at(-1)?.data??null,h,s.piiSalt),_=async()=>r+1>=5?(e.log.error(`several-signer envelope not routed: the chain never settled`,{envelopeId:t}),`gave-up`):(await mf(e,t,n+6e4,r+1),`retry`);if(p.complete){let r=await Sr(s.docSha256??``,g.at(-1)?.data.hash??``);if(!(await I(i,t,s.status,`completed`,{completedAt:d,finalHash:r,updatedAt:d})).ok)return _();if(!await vr(o,g))throw Error(`audit chain contention`);return await ea(e.cron,t,n),`completed`}return g.length>0&&!await vr(o,g)?_():m?(await _f(e,s,m,f,n),`invited`):`audited`}async function _f(e,t,n,r,i){let a=M(i),o=await e.settings.get(`senderName`),s=await va(k(),void 0,t=>z(e).signers.updateIf(n,{where:{status:`pending`,waiting:!0},set:{tokenHash:t,invitedAt:a,waiting:!1}}));if(!s.value.applied)return;let{email:c,name:l}=s.value.data;await er(e).put(Ws(n),Gs(Zn({to:c,signerName:l,title:t.title,sender:tr(e,o),link:`${r}/sign/${s.token}`,expiresAt:t.expiresAt}),i))}async function vf(e,t){if(!e.name.startsWith(ff))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n==`string`&&n.length>0&&await gf(t,n,Date.now(),typeof r==`number`&&Number.isSafeInteger(r)?r:0),!0}const yf=`reminders`,bf=`reminders-more`;function xf(e,t){let n=t.find(e=>e.status!==`signed`);return e.routing===`sequential`&&n?.waiting===!0&&Fs(`sequential`,n,t)}async function Sf(e,t,n,r){let i=F(e);if(!i)return;let a=await e.settings.list(),o=e=>a.find(t=>t.key===e)?.value,s=o(`licenceKey`);if(!le(await t.check({settings:{get:async()=>s},site:e.site}),`new`).ok)return;let c=Vs(o(`reminderCadenceDays`)),{envelopes:l,signers:u}=z(e),d=await l.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{gt:M(n)}},orderBy:{expiresAt:`asc`},limit:50,...r?{cursor:r}:{}}),f=d.items.filter(e=>Date.parse(e.data.sentAt??``)+c*864e5<=n),p=f.flatMap(e=>e.data.signerIds),m=p.length>0?await u.getMany(p):new Map,h=e=>e.data.signerIds.flatMap(e=>{let t=m.get(e);return t?[{id:e,data:t}]:[]}),[g,..._]=f.flatMap(e=>h(e).filter(t=>Hs(e.data,t.data,{now:n,cadenceDays:c})).map(t=>({envelope:e,signer:t})));if(g)await Cf(e,g.envelope,g.signer,i,o(`senderName`),n);else{let t=f.find(e=>xf(e.data,h(e).map(e=>e.data)));t&&await mf(e,t.id,n)}if(_.length>0||d.hasMore&&d.cursor){let t=_.length>0?r:d.cursor;await e.cron?.schedule(bf,{schedule:M(n+6e4),...t?{data:{cursor:t}}:{}})}}async function Cf(e,t,n,r,i,a){let{signers:o,audit_events:s}=z(e),c=M(a),l=(n.data.reminders??0)+1,u=await va(k(),void 0,e=>o.updateIf(n.id,{where:{status:`pending`,tokenHash:n.data.tokenHash},set:{tokenHash:e,remindedAt:c,reminders:l}}));if(!u.value.applied)return!1;if(await er(e).put(Ws(n.id),Gs(Us({to:n.data.email,signerName:n.data.name,title:t.data.title,sender:tr(e,i),link:`${r}/sign/${u.token}`,expiresAt:t.data.expiresAt}),a)),!(await gr(s,t.id,Ls(n.data,c,l),{salt:t.data.piiSalt})).ok)throw Error(`audit chain contention`);return!0}async function wf(e,t,n,r=Date.now()){if(e.name===wn)return await t.cron?.schedule(yf,{schedule:`29 * * * *`}),!1;if(e.name!==yf&&e.name!==bf)return!1;let i=e.name===bf?e.data?.cursor:void 0;return await Sf(t,n,r,typeof i==`string`&&i.length>0?i:void 0),!0}const Tf=`mcp-send-`,Ef=e=>(uf.routes??{})[e].handler,Df=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{},Of=()=>({ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}});async function kf(e,t){let{signers:n,routing:r,...i}=Df(e.input);if(!Array.isArray(n)||n.length<1||n.length>10)return V([{path:`signers`,code:`INVALID_SIGNERS`}]);if(n.length>1)return qs({...e,input:{...i,signers:n,routing:r??`parallel`}},t);if(!F(t))return Of();let a=await Ef(`envelopes/create`)({...e,input:{...i,signer:n[0]}},t);if(!a.envelope)return a;let o=e.user?.id;return await t.cron?.schedule(`${Tf}${a.envelope.id}`,{schedule:M(),data:{envelopeId:a.envelope.id,...typeof o==`string`?{userId:o}:{}}}),{...a,sending:!0}}async function Af(e,t){if(!e.name.startsWith(Tf))return!1;let n=e.data?.userId;return await Ef(`envelopes/send`)({input:{id:e.name.slice(9)},...typeof n==`string`?{user:{id:n}}:{}},t),!0}async function jf(e,t){let{snapshot:n,...r}=Df(await Ef(`envelopes/get`)(e,t));return r}async function Mf(e,t){let n=Df(e.input).id;if(typeof n!=`string`||n.length===0||n.length>100)return V([{path:`id`,code:`INVALID_INPUT`}]);let r=F(t);if(!r)return Of();let{envelopes:i,signers:a}=z(t),o=await i.get(n);if(!o)return H(`ENVELOPE_NOT_FOUND`);if(o.status!==`sent`&&o.status!==`in_progress`)return H(`ENVELOPE_CLOSED`);let s=Date.now(),c=await a.getMany(o.signerIds),[l,...u]=o.signerIds.flatMap(e=>{let t=c.get(e);return t&&Hs(o,t,{now:s,cadenceDays:.041666666666666664})?[{id:e,data:t}]:[]});return l?await Cf(t,{id:n,data:o},l,r,await t.settings.get(`senderName`),s)?{ok:!0,reminded:{signer:l.data.order},remaining:u.length}:{ok:!1,error:{code:`SIGNER_CHANGED`,message:`The signer's status changed. Try again.`}}:{ok:!1,error:{code:`NOTHING_TO_REMIND`,message:`No signer is due a reminder: each has signed, is not yet invited, was emailed in the last hour or has had the most reminders.`}}}const Nf=e=>({permission:`plugins:manage`,handler:e});function Pf(e){return{"pro/mcp/templates":Nf(Ef(`templates/list`)),"pro/mcp/send":e.gate(`esign/envelope-send`,Nf(kf)),"pro/mcp/status":Nf(jf),"pro/mcp/remind":e.gate(`new`,Nf(Mf)),"pro/mcp/void":Nf(Ef(`envelopes/void`))}}const Ff=[`sent`,`in_progress`],If=(e,t,n={})=>({ok:!1,error:{code:e,message:t,...n}}),Lf=(e,t)=>typeof e==`object`&&e?e[t]:void 0;function Rf(e){let t=Lf(e,`token`);return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function zf(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}async function Bf(e,t,n,r,i){return!(await xn({get:t=>e.kv.get(t),set:(t,n)=>e.kv.set(t,n)},t.requestMeta?.ip??`unknown`,i,{scope:n,limit:r,windowSeconds:600,salt:`esign-otp/1`})).ok}async function Vf(e,t,n){let{signers:r,envelopes:i}=z(e),a=(await r.query({where:{tokenHash:await A(t)},limit:1})).items[0];if(!a||a.data.status!==`pending`||!await me(t,a.data.tokenHash))return{error:H(`SIGNING_TOKEN_INVALID`)};let o=a.data.envelopeId,s=await i.get(o);return s?Ff.includes(s.status)?s.expiresAt!==null&&s.expiresAt<=n?{error:H(`SIGNING_TOKEN_EXPIRED`)}:s.otp?{signer:{id:a.id,data:a.data},envelope:s,envelopeId:o}:{error:If(`OTP_NOT_REQUIRED`,`This document does not need a code.`)}:{error:H(`ENVELOPE_CLOSED`)}:{error:H(`ENVELOPE_NOT_FOUND`)}}const Hf=e=>`Your code to sign: ${e.title}`,Uf=e=>`Your one-time code is ${e}\n\nIt expires in ${ho/6e4} minutes. Enter it on the signing page to continue. If you did not ask for it, ignore this email; nobody can sign for you without it. Never share this code.`;async function Wf(e,t){if(zf(e.request))return H(`TOKEN_IN_QUERY`);let n=Rf(e.input);if(n===null)return V([{path:`token`,code:`INVALID_INPUT`}]);let r=Date.now();if(await Bf(t,e,`otp-send`,10,r))return H(`RATE_LIMITED`);let i=await Vf(t,n,M(r));if(i.error)return i.error;let{signer:a,envelope:o}=i;if(a.data.otpVerifiedAt)return{ok:!0,sent:!1,verified:!0};let s=a.data.otp??void 0,c=bo(s,r);if(!c.ok)return c.code===`OTP_WAIT`?If(`OTP_WAIT`,`A code was sent a moment ago. Please wait before asking for another.`,{retryAfterSeconds:c.retryAfterSeconds}):H(`RATE_LIMITED`);let l=_o();await z(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:await xo(l,a.id,r,c),otpTries:0}});try{if(!t.email)throw Error(`no email`);await t.email.send({to:a.data.email,subject:Hf(o),text:Uf(l)})}catch{return await z(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:s??null,otpTries:a.data.otpTries??5}}),If(`OTP_SEND_FAILED`,`We could not email a code. Please try again shortly.`)}return{ok:!0,sent:!0,expiresInSeconds:ho/1e3}}async function Gf(e,t){if(zf(e.request))return H(`TOKEN_IN_QUERY`);let n=Rf(e.input),r=vo(Lf(e.input,`code`));if(n===null||r===null)return V([{path:n===null?`token`:`code`,code:`INVALID_INPUT`}]);let i=Date.now();if(await Bf(t,e,`otp-verify`,30,i))return H(`RATE_LIMITED`);let a=M(i),o=await Vf(t,n,a);if(o.error)return o.error;let{signer:s,envelope:c,envelopeId:l}=o;if(s.data.otpVerifiedAt)return{ok:!0,verified:!0};let{signers:u,audit_events:d}=z(t),f=s.data.otp??void 0,p=s.data.otpTries??5,m=await So(f&&{...f,attempts:p},r,s.id,i),h=()=>If(`OTP_LOCKED`,`Too many wrong codes. Ask for a new code.`);if(!m.ok&&m.code!==`OTP_INVALID`)return m.code===`OTP_EXPIRED`?If(`OTP_EXPIRED`,`That code has expired. Ask for a new code.`):h();if(!(await u.updateIf(s.id,{where:{status:`pending`,otpTries:{lt:5}},delta:{otpTries:{inc:1}}})).applied)return h();if(!m.ok)return If(`OTP_INVALID`,`That code is not right.`,{attemptsLeft:m.attemptsLeft});if(!(await gr(d,l,{type:`otp.verified`,at:a,actor:`signer`,data:{method:`email`,...Ka(c.signerIds.length>1?s.data.order:void 0)},personal:{...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}}},{salt:c.piiSalt})).ok)throw Error(`audit chain contention`);return await u.updateIf(s.id,{where:{status:`pending`,otpVerifiedAt:null},set:{otpVerifiedAt:a,otp:null}}),{ok:!0,verified:!0}}const Kf=/^[!-~]$/;function qf(e){let t=`/`;for(let n of e){let e=n.charCodeAt(0);t+=Kf.test(n)&&!`()<>[]{}/%#`.includes(n)?n:`#${(e&255).toString(16).padStart(2,`0`)}`}return t}function Jf(e){if(!Number.isFinite(e))return`0`;if(Number.isInteger(e))return String(e);let t=e.toFixed(6).replace(/0+$/,``).replace(/\.$/,``);return t===`-0`?`0`:t}function Q(e){if(e===null)return`null`;if(typeof e==`boolean`)return String(e);if(typeof e==`number`)return Jf(e);if(e instanceof jo)return qf(e.name);if(e instanceof No)return`${e.num} ${e.gen} R`;if(e instanceof Mo){let t=``;for(let n=0;n<e.bytes.length;n++)t+=e.bytes.charCodeAt(n).toString(16).padStart(2,`0`);return`<${t}>`}return Array.isArray(e)?`[${e.map(Q).join(` `)}]`:`<<${[...e].map(([e,t])=>`${qf(e)} ${Q(t)}`).join(` `)}>>`}const Yf=(e,t=``)=>`<< /Length ${e.length}${t} >>\nstream\n${e}\nendstream`;var Xf=class{objects=new Map;next;constructor(e){this.file=e,this.next=e.size}add(e){let t=new No(this.next++,0);return this.objects.set(t.num,{gen:0,body:e}),t}replace(e,t){this.objects.set(e.num,{gen:this.file.genOf(e.num),body:t})}bytes(){let{file:e}=this,t=e.bytes.length,n=e.bytes[t-1],r=n===10||n===13?``:`
|
|
54
54
|
`,i=new Map,a=(e,n,a)=>{i.set(e,t+r.length),r+=`${e} ${n} obj\n${a}\nendobj\n`};for(let e of[...this.objects.keys()].sort((e,t)=>e-t)){let t=this.objects.get(e);a(e,t.gen,t.body)}let o=[`Root`,`Info`,`ID`].filter(t=>e.trailer.has(t)).map(t=>` ${qf(t)} ${Q(e.trailer.get(t))}`).join(``),s=e=>{let t=[];for(let n of e){let e=t.at(-1);e&&e[0]+e[1].length===n?e[1].push(n):t.push([n,[n]])}return t},c=e=>this.objects.get(e)?.gen??0;if(e.xrefKind===`table`){let n=t+r.length;r+=`xref
|
|
55
55
|
`;for(let[e,t]of s([...i.keys()].sort((e,t)=>e-t))){r+=`${e} ${t.length}\n`;for(let e of t)r+=`${String(i.get(e)).padStart(10,`0`)} ${String(c(e)).padStart(5,`0`)} n \n`}r+=`trailer\n<< /Size ${this.next}${o} /Prev ${e.startxref} >>\nstartxref\n${n}\n%%EOF\n`}else{let n=this.next++,a=t+r.length;i.set(n,a);let l=[...i.keys()].sort((e,t)=>e-t),u=``;for(let e of l){let t=i.get(e),n=c(e);u+=String.fromCharCode(1,t>>>24&255,t>>>16&255,t>>>8&255,t&255,n>>8&255,n&255)}let d=s(l).map(([e,t])=>`${e} ${t.length}`).join(` `);r+=`${n} 0 obj\n${Yf(u,` /Type /XRef /Size ${this.next} /W [1 4 2] /Index [${d}]${o} /Prev ${e.startxref}`)}\nendobj\nstartxref\n${a}\n%%EOF\n`}let l=new Uint8Array(t+r.length);l.set(e.bytes);for(let e=0;e<r.length;e++)l[t+e]=r.charCodeAt(e);return l}};function Zf(e){let[t,n,r,i]=e.box;switch(e.rotate){case 90:return[0,1,-1,0,r,n];case 180:return[-1,0,0,-1,r,i];case 270:return[0,-1,1,0,t,i];default:return[1,0,0,1,t,n]}}function Qf(e,t,n){let r=[];for(let i of e){let{x:e,y:a,w:o,h:s}=i.box,c=t-a-s;if(i.kind===`text`){let t=Gt(i.text.replace(/\s+/g,` `).trim());if(!t)continue;let a=i.font===`italic`?`italic`:`regular`,l=Jt(t,1,a),u=Math.max(4,Math.min(14,s*.75,l>0?(o-2)/l:14)),d=c+Math.max(0,(s-u*.72)/2),f=a===`italic`?n.italic:n.regular;r.push(`BT ${qf(f)} ${N(u)} Tf 0 0 0 rg ${N(e+1)} ${N(d)} Td ${Xt(t)} Tj ET`)}else{let t=[`0.05 0.1 0.45 RG 1.2 w 1 J 1 j`],n=t=>N(e+Math.min(1,Math.max(0,typeof t==`number`?t:0))*o),a=e=>N(c+s-Math.min(1,Math.max(0,typeof e==`number`?e:0))*s);for(let e of i.strokes){let r=e.filter(e=>Array.isArray(e)&&e.length>=2),[i]=r;if(i){t.push(`${n(i[0])} ${a(i[1])} m`);for(let e of r.length===1?r:r.slice(1))t.push(`${n(e[0])} ${a(e[1])} l`);t.push(`S`)}}t.length>1&&r.push(t.join(`
|
|
56
56
|
`))}}return r.join(`
|
package/package.json
CHANGED