@josephomills/esign 0.2.2
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/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/ports-DtICqgEf.d.cts +553 -0
- package/dist/ports-DtICqgEf.d.ts +553 -0
- package/dist/prisma/index.cjs +510 -0
- package/dist/prisma/index.cjs.map +1 -0
- package/dist/prisma/index.d.cts +48 -0
- package/dist/prisma/index.d.ts +48 -0
- package/dist/prisma/index.js +508 -0
- package/dist/prisma/index.js.map +1 -0
- package/dist/server/index.cjs +1016 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +357 -0
- package/dist/server/index.d.ts +357 -0
- package/dist/server/index.js +974 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +84 -0
- package/prisma/esign-models.prisma +166 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { S as SubjectSelection, E as EsignChannel, R as ResendPolicy, P as PersistencePort, a as SubjectsPort, N as NotifierPort, C as Clock, b as SkippedSubject, c as Placement, d as StoragePort, e as SigningDocumentVersionDTO, f as SigningDocumentDTO, g as SigningRequestDTO, H as HooksPort, h as EsignConfig, V as VersionPolicy, i as SubjectSigningStatus, j as CoverageReport, k as CampaignStatsRow, D as DocumentStatsRow, l as StatsRange, m as ScopeStatsRow, O as OutstandingRequest, n as SubjectTypeDescriptor } from '../ports-DtICqgEf.js';
|
|
2
|
+
export { A as ACTIVE_STATUSES, o as AuthPort, p as DeclineInput, q as ESIGN_CHANNELS, r as ESIGN_STATUSES, s as EsignStatus, G as GroupBreakdown, t as NewAuditEventRow, u as NewRequestRow, v as NotifierAttachment, w as Recipient, x as RequestSummary, y as SigningAuditEventDTO, z as SigningCampaignDTO, B as StatusCountMap, F as SubjectFilter, I as SubjectFilterField, J as SubjectSigningState, K as SubjectSummary, L as SubmitSignatureInput, T as TERMINAL_STATUSES, M as assertTransition, Q as canTransition, U as declineSchema, W as esignChannelSchema, X as isActive, Y as isTerminal, Z as placementSchema, _ as subjectSelectionSchema, $ as submitSignatureSchema } from '../ports-DtICqgEf.js';
|
|
3
|
+
import { PDFDocument } from 'pdf-lib';
|
|
4
|
+
import { ZodType } from 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tamper-evident audit log (Level-1 seal). Every signing request accumulates an
|
|
8
|
+
* append-only chain of events (CREATED → NOTIFIED → VIEWED → CONSENTED → SIGNED
|
|
9
|
+
* → SEALED). Each link's `hash` covers the previous hash plus this link's
|
|
10
|
+
* contents, so altering any earlier event invalidates every hash after it. The
|
|
11
|
+
* chain is rendered onto the sealed PDF's certificate page and re-checkable with
|
|
12
|
+
* `verifyChain`.
|
|
13
|
+
*/
|
|
14
|
+
interface AuditEventInput {
|
|
15
|
+
type: string;
|
|
16
|
+
payload: Record<string, unknown>;
|
|
17
|
+
/** ISO instant; passed in (never `Date.now()`) so seals are reproducible. */
|
|
18
|
+
occurredAt: string;
|
|
19
|
+
}
|
|
20
|
+
interface AuditLink extends AuditEventInput {
|
|
21
|
+
seq: number;
|
|
22
|
+
prevHash: string | null;
|
|
23
|
+
hash: string;
|
|
24
|
+
}
|
|
25
|
+
/** Deterministic JSON: object keys sorted, `undefined` normalized to null. */
|
|
26
|
+
declare function canonicalize(value: unknown): string;
|
|
27
|
+
/** The hash bound into a link: sha256(prevHash | seq | type | occurredAt | payload). */
|
|
28
|
+
declare function linkHash(prevHash: string | null, seq: number, type: string, occurredAt: string, payload: unknown): string;
|
|
29
|
+
/** Append one event to a chain (or start it when `prev` is null). */
|
|
30
|
+
declare function appendEvent(prev: AuditLink | null, input: AuditEventInput): AuditLink;
|
|
31
|
+
/** Fold a list of events into a verified chain. */
|
|
32
|
+
declare function buildChain(inputs: AuditEventInput[]): AuditLink[];
|
|
33
|
+
/** Recompute every hash; `brokenAt` is the seq of the first bad link, else null. */
|
|
34
|
+
declare function verifyChain(links: AuditLink[]): {
|
|
35
|
+
ok: boolean;
|
|
36
|
+
brokenAt: number | null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Persist one audit link and return it, so the caller can thread the chain tip
|
|
41
|
+
* into the next event. Shared by the fan-out here and the signer submit handler.
|
|
42
|
+
*/
|
|
43
|
+
declare function recordEvent(persistence: PersistencePort, requestId: string, prev: AuditLink | null, input: AuditEventInput): Promise<AuditLink>;
|
|
44
|
+
interface ChannelContent {
|
|
45
|
+
subject: string;
|
|
46
|
+
body: string;
|
|
47
|
+
}
|
|
48
|
+
type CampaignContentBuilder = (ctx: {
|
|
49
|
+
documentTitle: string;
|
|
50
|
+
note: string | null;
|
|
51
|
+
recipientName: string;
|
|
52
|
+
}) => ChannelContent;
|
|
53
|
+
interface CreateCampaignDeps {
|
|
54
|
+
persistence: PersistencePort;
|
|
55
|
+
subjects: SubjectsPort;
|
|
56
|
+
notifier: NotifierPort;
|
|
57
|
+
clock: Clock;
|
|
58
|
+
baseUrl: string;
|
|
59
|
+
defaultExpiryDays: number;
|
|
60
|
+
content?: CampaignContentBuilder;
|
|
61
|
+
}
|
|
62
|
+
interface CreateCampaignArgs {
|
|
63
|
+
/** Opaque host scope (estate id / country id / null) — already authorized by the route. */
|
|
64
|
+
scopeId?: string | null;
|
|
65
|
+
documentVersionId: string;
|
|
66
|
+
selection: SubjectSelection;
|
|
67
|
+
channels: EsignChannel[];
|
|
68
|
+
note?: string | null;
|
|
69
|
+
emailReceipt?: boolean;
|
|
70
|
+
expiresInDays?: number;
|
|
71
|
+
resendPolicy?: ResendPolicy;
|
|
72
|
+
createdById?: string | null;
|
|
73
|
+
}
|
|
74
|
+
interface CreateCampaignResult {
|
|
75
|
+
/** null when the (filtered) target group resolved to nobody — e.g. "uncovered" with no new subjects. */
|
|
76
|
+
campaignId: string | null;
|
|
77
|
+
sent: number;
|
|
78
|
+
skipped: SkippedSubject[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Send a version to a target group. Resolves recipients server-side via the
|
|
82
|
+
* SubjectsPort, applies the resend policy by diffing against existing requests,
|
|
83
|
+
* mints no-login tokens, creates the request rows, and fans out one notification
|
|
84
|
+
* per recipient × channel — recording a CREATED + per-send NOTIFIED audit chain.
|
|
85
|
+
*/
|
|
86
|
+
declare function createCampaign(deps: CreateCampaignDeps, args: CreateCampaignArgs): Promise<CreateCampaignResult>;
|
|
87
|
+
|
|
88
|
+
interface CreateDocumentInput {
|
|
89
|
+
scopeId?: string | null;
|
|
90
|
+
documentType?: string | null;
|
|
91
|
+
title: string;
|
|
92
|
+
audience?: SubjectSelection | null;
|
|
93
|
+
createdById?: string | null;
|
|
94
|
+
}
|
|
95
|
+
declare function createDocument(persistence: PersistencePort, input: CreateDocumentInput): Promise<SigningDocumentDTO>;
|
|
96
|
+
/** A new version supplies its PDF either by an already-uploaded key or raw bytes. */
|
|
97
|
+
type VersionSource = {
|
|
98
|
+
objectKey: string;
|
|
99
|
+
} | {
|
|
100
|
+
pdfBytes: Uint8Array;
|
|
101
|
+
scopeId?: string | null;
|
|
102
|
+
};
|
|
103
|
+
interface AddVersionInput {
|
|
104
|
+
documentId: string;
|
|
105
|
+
placement: Placement;
|
|
106
|
+
source: VersionSource;
|
|
107
|
+
changeNote?: string | null;
|
|
108
|
+
createdById?: string | null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Add an immutable version to a document: validate + hash the source PDF, store
|
|
112
|
+
* it (when bytes were passed), persist the next-numbered version, and point the
|
|
113
|
+
* document at it as current.
|
|
114
|
+
*/
|
|
115
|
+
declare function addVersion(deps: {
|
|
116
|
+
persistence: PersistencePort;
|
|
117
|
+
storage: StoragePort;
|
|
118
|
+
}, input: AddVersionInput): Promise<SigningDocumentVersionDTO>;
|
|
119
|
+
|
|
120
|
+
interface SignDeps {
|
|
121
|
+
persistence: PersistencePort;
|
|
122
|
+
storage: StoragePort;
|
|
123
|
+
clock: Clock;
|
|
124
|
+
notifier: NotifierPort;
|
|
125
|
+
hooks?: HooksPort;
|
|
126
|
+
}
|
|
127
|
+
interface SigningView {
|
|
128
|
+
request: SigningRequestDTO;
|
|
129
|
+
/** Source PDF object key + placement for the signer page to render. */
|
|
130
|
+
sourceObjectKey: string;
|
|
131
|
+
placement: Placement;
|
|
132
|
+
documentTitle: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Data for the public signing page. Returns null for unknown / expired / revoked
|
|
136
|
+
* / already-finished requests so the host shows one "unavailable" screen.
|
|
137
|
+
*/
|
|
138
|
+
declare function getSigningView(deps: Pick<SignDeps, "persistence" | "clock">, token: string): Promise<SigningView | null>;
|
|
139
|
+
/** Mark first view PENDING→VIEWED, recording a VIEWED audit event. Idempotent. */
|
|
140
|
+
declare function recordView(deps: Pick<SignDeps, "persistence" | "clock" | "hooks">, token: string): Promise<void>;
|
|
141
|
+
interface SubmitInput {
|
|
142
|
+
token: string;
|
|
143
|
+
signaturePng: Uint8Array;
|
|
144
|
+
signerName: string;
|
|
145
|
+
ip: string | null;
|
|
146
|
+
userAgent: string | null;
|
|
147
|
+
}
|
|
148
|
+
interface SubmitResult {
|
|
149
|
+
requestId: string;
|
|
150
|
+
sealedObjectKey: string;
|
|
151
|
+
alreadySigned: boolean;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The signer submit: consent → seal → store → persist SIGNED → fire hook →
|
|
155
|
+
* optional emailed receipt. Idempotent — a re-submit of a signed request returns
|
|
156
|
+
* the existing sealed key instead of re-sealing.
|
|
157
|
+
*/
|
|
158
|
+
declare function submitSignature(deps: SignDeps, input: SubmitInput): Promise<SubmitResult>;
|
|
159
|
+
interface DeclineRequestInput {
|
|
160
|
+
token: string;
|
|
161
|
+
reason: string | null;
|
|
162
|
+
}
|
|
163
|
+
/** Signer declines: PENDING/VIEWED → DECLINED, recording a DECLINED event. */
|
|
164
|
+
declare function declineRequest(deps: Pick<SignDeps, "persistence" | "clock" | "hooks">, input: DeclineRequestInput): Promise<void>;
|
|
165
|
+
|
|
166
|
+
type RouteCtx$1 = {
|
|
167
|
+
params: {
|
|
168
|
+
token: string;
|
|
169
|
+
} | Promise<{
|
|
170
|
+
token: string;
|
|
171
|
+
}>;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* POST the signer action. `?action=decline` declines; otherwise it submits the
|
|
175
|
+
* signature (consent → seal → SIGNED). Mount at `app/sign/[token]/submit/route.ts`.
|
|
176
|
+
*/
|
|
177
|
+
declare function createSignActionsRoute(deps: SignDeps): {
|
|
178
|
+
POST: (req: Request, ctx: RouteCtx$1) => Promise<Response>;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
type RouteCtx = {
|
|
182
|
+
params: {
|
|
183
|
+
token: string;
|
|
184
|
+
} | Promise<{
|
|
185
|
+
token: string;
|
|
186
|
+
}>;
|
|
187
|
+
};
|
|
188
|
+
interface SignServeDeps {
|
|
189
|
+
persistence: PersistencePort;
|
|
190
|
+
storage: StoragePort;
|
|
191
|
+
clock: Clock;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* GET the source PDF for the signer page, gated only by the (unguessable) token.
|
|
195
|
+
* Bad / expired / revoked / finished tokens all 404 the same way (no oracle).
|
|
196
|
+
* Mount at `app/api/esign/source/[token]/route.ts`; the host should rate-limit.
|
|
197
|
+
*/
|
|
198
|
+
declare function createSignServeRoute(deps: SignServeDeps): {
|
|
199
|
+
GET: (req: Request, ctx: RouteCtx) => Promise<Response>;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* No-login signer token. We follow the share-link convention from the host
|
|
204
|
+
* apps: generate a random token, return the cleartext exactly once (it goes
|
|
205
|
+
* only into the `/sign/<token>` URL), and persist nothing but its sha256. A
|
|
206
|
+
* leaked database never yields a usable link.
|
|
207
|
+
*/
|
|
208
|
+
interface SigningToken {
|
|
209
|
+
/** Goes into the signer URL only — never stored. */
|
|
210
|
+
cleartext: string;
|
|
211
|
+
/** sha256(cleartext) — the value stored in `SigningRequest.tokenHash`. */
|
|
212
|
+
tokenHash: string;
|
|
213
|
+
}
|
|
214
|
+
/** sha256 of a string or bytes, lowercase hex (64 chars). */
|
|
215
|
+
declare function sha256Hex(input: string | Uint8Array): string;
|
|
216
|
+
/** A fresh signing token. `bytes` of entropy, base64url-encoded cleartext. */
|
|
217
|
+
declare function newSigningToken(bytes?: number): SigningToken;
|
|
218
|
+
|
|
219
|
+
type ResolvedEsignConfig<S> = EsignConfig<S> & Required<Pick<EsignConfig<S>, "routeBasePath" | "presignTtlS" | "defaultExpiryDays" | "clock">>;
|
|
220
|
+
interface SubjectSigningStatusArgs {
|
|
221
|
+
subjectType: string;
|
|
222
|
+
subjectId: string;
|
|
223
|
+
documentId?: string;
|
|
224
|
+
documentType?: string;
|
|
225
|
+
versionPolicy: VersionPolicy;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The wired runtime: every engine function bound to the host's ports, plus the
|
|
229
|
+
* route-handler factories the host mounts. Mirrors milestone-grid's
|
|
230
|
+
* `configureMilestoneGrid(...) → { routes, ... }`.
|
|
231
|
+
*/
|
|
232
|
+
interface EsignRuntime<S> {
|
|
233
|
+
config: ResolvedEsignConfig<S>;
|
|
234
|
+
newSigningToken: typeof newSigningToken;
|
|
235
|
+
createDocument(input: CreateDocumentInput): Promise<SigningDocumentDTO>;
|
|
236
|
+
addVersion(input: AddVersionInput): Promise<SigningDocumentVersionDTO>;
|
|
237
|
+
createCampaign(args: CreateCampaignArgs): Promise<CreateCampaignResult>;
|
|
238
|
+
getSigningView(token: string): Promise<SigningView | null>;
|
|
239
|
+
recordView(token: string): Promise<void>;
|
|
240
|
+
submitSignature(input: SubmitInput): Promise<SubmitResult>;
|
|
241
|
+
declineRequest(input: DeclineRequestInput): Promise<void>;
|
|
242
|
+
subjectSigningStatus(args: SubjectSigningStatusArgs): Promise<SubjectSigningStatus>;
|
|
243
|
+
documentCoverage(documentId: string): Promise<CoverageReport>;
|
|
244
|
+
campaignStats(campaignId: string): Promise<CampaignStatsRow>;
|
|
245
|
+
documentStats(documentId: string): Promise<DocumentStatsRow>;
|
|
246
|
+
scopeStats(scopeId: string | null, range?: StatsRange): Promise<ScopeStatsRow>;
|
|
247
|
+
outstandingRequests(filter: {
|
|
248
|
+
scopeId?: string | null;
|
|
249
|
+
documentId?: string;
|
|
250
|
+
campaignId?: string;
|
|
251
|
+
now: Date;
|
|
252
|
+
limit?: number;
|
|
253
|
+
}): Promise<OutstandingRequest[]>;
|
|
254
|
+
routes: {
|
|
255
|
+
signServe: ReturnType<typeof createSignServeRoute>;
|
|
256
|
+
signActions: ReturnType<typeof createSignActionsRoute>;
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
declare function configureEsign<S>(opts: EsignConfig<S>): EsignRuntime<S>;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Build a SubjectsPort from a list of host-defined subject-type descriptors.
|
|
263
|
+
* The package renders targeting from `groupField` / `filterFields` and calls
|
|
264
|
+
* the descriptor's enumeration/resolution methods; it never learns what a
|
|
265
|
+
* "MISSIONARY" or "APARTMENT" actually is.
|
|
266
|
+
*/
|
|
267
|
+
declare function registerSubjectTypes(types: SubjectTypeDescriptor[]): SubjectsPort;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* A 16-char unique id, matching the host `@db.VarChar(16)` convention. The
|
|
271
|
+
* package generates ids in code (the Prisma fragment carries no `@default`), so
|
|
272
|
+
* every esign-owned row gets a uid the same way across dhm-estates / flc-missions
|
|
273
|
+
* / flc-hr. Rejection sampling keeps the distribution uniform (no modulo bias).
|
|
274
|
+
*/
|
|
275
|
+
declare function uid(size?: number): string;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Human-readable signature certificate appended as the final page of every
|
|
279
|
+
* sealed PDF. It prints the signer, the document content SHA-256, the audit
|
|
280
|
+
* chain tip, and the full event log — so the seal is verifiable by eye, and the
|
|
281
|
+
* printed hashes let anyone re-check integrity out of band.
|
|
282
|
+
*/
|
|
283
|
+
interface CertInfo {
|
|
284
|
+
documentTitle: string;
|
|
285
|
+
signerName: string;
|
|
286
|
+
signedAt: string;
|
|
287
|
+
signerIp: string | null;
|
|
288
|
+
requestId: string;
|
|
289
|
+
/** sha256 of the flattened, signature-stamped content (pre-certificate). */
|
|
290
|
+
documentSha256: string;
|
|
291
|
+
/** The audit chain tip (SigningRequest.finalAuditHash). */
|
|
292
|
+
finalHash: string;
|
|
293
|
+
links: AuditLink[];
|
|
294
|
+
}
|
|
295
|
+
declare function renderAuditCertificatePage(pdf: PDFDocument, info: CertInfo): Promise<void>;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* The Level-1 seal. Loads the version's source PDF, stamps the signature within
|
|
299
|
+
* the manager's placement box, appends SIGNED + SEALED audit links, renders the
|
|
300
|
+
* certificate page, and returns the flattened bytes plus the content hash and
|
|
301
|
+
* chain tip. Pure + deterministic: a fixed input (incl. `signedAt`) yields
|
|
302
|
+
* byte-identical output, so `sealedSha256` is reproducible and testable.
|
|
303
|
+
*
|
|
304
|
+
* `documentSha256` is the hash of the stamped content *before* the certificate
|
|
305
|
+
* page (the bytes that were actually signed); `sealedSha256` covers the final
|
|
306
|
+
* file. A future Level-2 PAdES seal wraps the returned `sealedPdf` unchanged.
|
|
307
|
+
*/
|
|
308
|
+
interface SealInput {
|
|
309
|
+
sourcePdf: Uint8Array;
|
|
310
|
+
/** PNG bytes of the drawn or typed signature. */
|
|
311
|
+
signaturePng: Uint8Array;
|
|
312
|
+
placement: Placement;
|
|
313
|
+
signerName: string;
|
|
314
|
+
/** ISO instant — also pins the PDF metadata dates for reproducibility. */
|
|
315
|
+
signedAt: string;
|
|
316
|
+
signerIp: string | null;
|
|
317
|
+
documentTitle: string;
|
|
318
|
+
requestId: string;
|
|
319
|
+
/** Existing chain (CREATED…CONSENTED). SIGNED + SEALED are appended here. */
|
|
320
|
+
priorChain: AuditLink[];
|
|
321
|
+
}
|
|
322
|
+
interface SealResult {
|
|
323
|
+
sealedPdf: Uint8Array;
|
|
324
|
+
sealedSha256: string;
|
|
325
|
+
documentSha256: string;
|
|
326
|
+
finalHash: string;
|
|
327
|
+
/** The SIGNED and SEALED links — the caller persists them. */
|
|
328
|
+
newLinks: AuditLink[];
|
|
329
|
+
}
|
|
330
|
+
declare function sealPdf(input: SealInput): Promise<SealResult>;
|
|
331
|
+
|
|
332
|
+
interface CoverageDeps {
|
|
333
|
+
persistence: PersistencePort;
|
|
334
|
+
subjects: SubjectsPort;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Re-derive a document's coverage from the LIVE group (via the stored audience
|
|
338
|
+
* selection) so subjects added after a send are detected. Buckets every subject
|
|
339
|
+
* into signed / outstanding / needs-resign / uncovered / departed.
|
|
340
|
+
*/
|
|
341
|
+
declare function documentCoverage(deps: CoverageDeps, documentId: string): Promise<CoverageReport>;
|
|
342
|
+
|
|
343
|
+
declare function parseBody<T>(req: Request, schema: ZodType<T>): Promise<T>;
|
|
344
|
+
declare function ok(data: unknown, init?: ResponseInit): Response;
|
|
345
|
+
/** Best-effort client IP from forwarding headers (for the audit trail). */
|
|
346
|
+
declare function clientIp(req: Request): string | null;
|
|
347
|
+
|
|
348
|
+
type EsignErrorCode = "UNAUTHENTICATED" | "FORBIDDEN" | "NOT_FOUND" | "INVALID_INPUT" | "CONFLICT" | "GONE" | "RATE_LIMITED" | "PAYLOAD_TOO_LARGE" | "STORAGE_ERROR" | "INTERNAL";
|
|
349
|
+
declare class EsignError extends Error {
|
|
350
|
+
readonly code: EsignErrorCode;
|
|
351
|
+
readonly details?: unknown;
|
|
352
|
+
readonly status: number;
|
|
353
|
+
constructor(code: EsignErrorCode, message: string, details?: unknown);
|
|
354
|
+
}
|
|
355
|
+
declare function toErrorResponse(err: unknown): Response;
|
|
356
|
+
|
|
357
|
+
export { type AddVersionInput, type AuditEventInput, type AuditLink, type CampaignContentBuilder, CampaignStatsRow, type CertInfo, type ChannelContent, Clock, type CoverageDeps, CoverageReport, type CreateCampaignArgs, type CreateCampaignDeps, type CreateCampaignResult, type CreateDocumentInput, type DeclineRequestInput, DocumentStatsRow, EsignChannel, EsignConfig, EsignError, type EsignErrorCode, type EsignRuntime, HooksPort, NotifierPort, OutstandingRequest, PersistencePort, Placement, ResendPolicy, type ResolvedEsignConfig, ScopeStatsRow, type SealInput, type SealResult, type SignDeps, type SignServeDeps, SigningDocumentDTO, SigningDocumentVersionDTO, SigningRequestDTO, type SigningToken, type SigningView, SkippedSubject, StatsRange, StoragePort, SubjectSelection, SubjectSigningStatus, type SubjectSigningStatusArgs, SubjectTypeDescriptor, SubjectsPort, type SubmitInput, type SubmitResult, VersionPolicy, type VersionSource, addVersion, appendEvent, buildChain, canonicalize, clientIp, configureEsign, createCampaign, createDocument, createSignActionsRoute, createSignServeRoute, declineRequest, documentCoverage, getSigningView, linkHash, newSigningToken, ok, parseBody, recordEvent, recordView, registerSubjectTypes, renderAuditCertificatePage, sealPdf, sha256Hex, submitSignature, toErrorResponse, uid, verifyChain };
|